Python编码规范

--<<PEP 0008 -- Style Guide for Python Code>>

令人讨厌的小人物身上有着愚蠢的一致性

--(A Foolish Consistency is the Hobgoblin of Little Minds)

  • 代码的统一是为了增强可读性,因此一个项目中代码风格的统一很重要;

  • 知道什么时候统一,什么时候不统一,观察不同的样例,选出自己喜欢的,多质疑,多探索;

  • 不打破向后兼容的特性正符合PEP8的特性;

    打破一条既定规则的几个好理由:

  • 当应用这条规则时将导致代码可读性下降,即便对某人来说,他已经习惯于按这条规则来阅读代码了。

  • 为了和周围的代码保持一致而打破规则 (也许是历史原因) -- 虽然这也是个清除其他人代码混乱的好机会 (在真正的 XP 风格中)。

  • 因为残留问题的代码先于引入准则而单程,而此时没有其他理由来修改这些代码;

  • 当代码需要保持与旧版本的Python的功能兼容,但代码却是风格指南不支持推荐的。

代码布局

--(Code lay-out)

(缩进)Indentation

<pre><code>Yes(正确):

Aligned with opening delimiter.

foo = long_function_name(var_one, var_two,
var_three, var_four)

More indentation included to distinguish this from the rest.

def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)

Hanging indents should add a level.

foo = long_function_name(
var_one, var_two,
var_three, var_four)

No(错误):

Arguments on first line forbidden when not using vertical alignment.

foo = long_function_name(var_one, var_two,
var_three, var_four)

Further indentation required as indentation is not distinguishable.

def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)`</code></pre>

对连续的行来说,空格4是可选的

--(The 4-space rule is optional for continuation lines.)

<pre><code>Optional:

Hanging indents may be indented to other than 4 spaces.(悬挂缩进不同于空格4)

foo = long_function_name(
var_one, var_two,
var_three, var_four)

当条件语句 if -statement 太长而需要多行显示的时候, 标记组合关键、增加一个空格、增加半开始括号、每行添加4-空格是很有价值的。这样可
能会产生if -statement中那些前面同样添加了4-空格的嵌套式语句的视觉冲突。PEP的做法没有很好的解决上述存在的嵌套语句的视觉混淆问题,
下面的样例中给出了一些可接受的做法,当然不仅限于此:

No extra indentation.

if (this_is_one_thing and
that_is_another_thing):
do_something()

Add a comment, which will provide some distinction in editors

supporting syntax highlighting.

if (this_is_one_thing and
that_is_another_thing):
# Since both conditions are true, we can frobnicate.
do_something()

Add some extra indentation on the conditional continuation line.

if (this_is_one_thing
and that_is_another_thing):
do_something()

闭合的另一半括号/中括号/大括号,可以与列表中最后一行第一个非空格元素对齐,如下:

my_list = [
1, 2, 3,
4, 5, 6,
]
result = some_function_that_takes_arguments(
'a', 'b', 'c',
'd', 'e', 'f',
)

也可以与构造列表的第一行的元素的第一个字符对齐, 如下:

my_list = [
1, 2, 3,
4, 5, 6,
]
result = some_function_that_takes_arguments(
'a', 'b', 'c',
'd', 'e', 'f',
)</code></pre>

(Tabs还是空格)Tabs or Spaces?

--空格space是缩进(indentation)的首选;

--Tabs,一般如果一开始就试图用tab键来实现缩进,后面才会继续用tab来唯一的实现缩进;

--python3不允许混合使用spacetab;

--python2倾向于将混合使用的spacetab转换为唯一的spqce;

最大代码行长度

--(Maximum Line Length)

--限制每行字符的最大长度为79个字符

--对于结构限制较少的文本字符串和注释,限定长度为72个字符

--可以根据开发团队适时需求,修改限定长度在80-100之间,但是文本字符串和注释还是72比较好

--可以使用转义字符\拼接,用例如下:
<pre><code>with open('/path/to/some/file/you/want/to/read') as file_1,
open('/path/to/some/file/being/written', 'w') as file_2:
file_2.write(file_1.read())

class Rectangle(Blob):

def __init__(self, width, height,
             color='black', emphasis=None, highlight=0):
    if (width == 0 and height == 0 and
            color == 'red' and emphasis == 'strong' or
            highlight > 100):
        raise ValueError("sorry, you lose")
    if width == 0 and height == 0 and (color == 'red' or
                                       emphasis is None):
        raise ValueError("I don't think so -- values are %s, %s" %
                         (width, height))
    Blob.__init__(self, width, height,
                  color, emphasis, highlight)</code></pre>

空行

--(Blank Lines)

--顶层函数和类的定义之间要空两行;

--类中的方法定义间要空一行;

--额外的空行可被用于 (保守的 (sparingly)) 分割相关函数群 (groups of related functions)。在一组相关的单句 (related one-liners) 中间可以省略空行 (例如一组哑元 (dummy implementations));

--在函数中使用空行时,请谨慎的用于表示一个逻辑段落 (logical sections);

--Python 接受 contrl-L (即 ^L) 换页符作为空白符 (whitespace);许多工具视这些 字符为分页符 (page separators),因此在你的文件中,可以用它们来为相关片段 (sections) 分页;

源文件编码

--(Source File Encoding)

--Python 核心发布中的代码应该始终使用 ASCII 或 Latin-1 编码(又名ISO-8859-1)。

--使用ASCII的文件不必有译码 cookie (coding cookie)。 Latin-1 仅当注释或文档字 符串涉及作者名字需要 Latin-1 时才被使用;另外使用 \x 转义字符是在字符串中包 含非 ASCII 数据的首选方法。

导入

--(imports)

  • -通常应该在单独的行中导入,例如:
    <pre><code>Yes:
    import os
    import sys
    No:
    import sys, os
    但是这样也是可以的:
    from subprocess import Popen, PIPE
    -- Imports 通常被放置在文件的顶部,仅在模块注释和文档字符串之后,在模块的全局变量和常量之前。
    Imports应该按照如下顺序成组安放:
    1 标准库的导入
    2 相关的第三方包的导入
    3 本地应用/库的特定导入
    你应该在每组导入之间放置一个空行。
    把任何相关 all 说明的放在 imports 之后。
    对于内部包的导入是非常不推荐使用相对导入的。对所有导入总是使用包的绝对路径。即使现在 PEP 328 7 在 Python 2.5 中被完整实现了,
    其 explicit relative imports 的风格也是不推荐的。绝对导入能更好的移植 (portable),通 常也更易读;
    从一个包含类的模块中导入类时,通常可以写成这样:
    from myclass import MyClass
    from foo.bar.yourclass import YourClass
    如果这样写导致了本地名字冲突,那么就这样写:
    import myclass import foo.bar.yourclass
    并使用 "myclass.MyClass" and "foo.bar.yourclass.YourClass"</code></pre>

无伤大雅的小问题

--(Pet Peeves)

  • 在以下情况尽量避免多余的空格:

    在括号,中括号,大括号内.

    <pre><code>Yes: spam(ham[1], {eggs: 2})
    No: spam( ham[ 1 ], { eggs: 2 } )</code></pre>

    在逗号,分号,句号前:

    <pre><code>Yes: if x == 4: print x, y; x, y = y, x
    No: if x == 4 : print x , y ; x , y = y , x</code></pre>

    当分片的时候,在[]中,冒号相当于一个二目运算符,而且具有在任一侧等价的位置,所有冒号必须有相同分量的空格,当然,当分片中分号两侧的参数缺省时,空格也缺省

    <pre><code>Yes:

    ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:]
    ham[lower:upper], ham[lower:upper:], ham[lower::step]
    ham[lower+offset : upper+offset]
    ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
    ham[lower + offset : upper + offset]
    No:

    ham[lower + offset:upper + offset]
    ham[1: 9], ham[1 :9], ham[1:9 :3]
    ham[lower : : upper]
    ham[ : upper]</code></pre>

    在左括号与函数名间

    <pre><code>Yes: spam(1)
    No: spam (1)</code></pre>

    在左中括号与参数名间:

    <pre><code>Yes: dct['key'] = lst[index]
    No: dct ['key'] = lst [index]</code></pre>

    定义变量的时候,变量名与赋值操作符之间多于一个空格.

    <pre><code>Yes:

    x = 1
    y = 2
    long_variable = 3
    No:

    x = 1
    y = 2
    long_variable = 3</code></pre>

其他建议

--(Other Recommendations)

  • 始终在这些二元运算符两边放置一个空格:

    assignment (=),
    augmented assignment (+=, -= etc.),
    comparisons (==, <, >, !=, <>, <=, >=, in, not in, is, is not),
    Booleans (and, or, not)

  • 在数学运算符两边使用空格:

    <pre><code>Yes:
    i = i + 1 submitted += 1 x = x 2 - 1 hypot2 = x x + y y c = (a + b) (a - b)
    No:
    i=i+1 submitted +=1 x = x2 - 1 hypot2 = xx + y*y c = (a+b) (a-b)</code></pre>

  • 不要在用于指定关键字参数 (keyword argument) 或默认参数值的 '=' 号周围使用空格。

    <pre><code>Yes:
    def complex(real, imag=0.0):
    return magic(r=real, i=imag)
    No:
    def complex(real, imag = 0.0):
    return magic(r = real, i = imag)</code></pre>

  • 复合语句 (Compound statements) (多条语句写在同一行) 一般不推荐。

    <pre><code>Yes:
    if foo == 'blah':
    do_blah_thing()
    do_one()
    do_two()
    do_three()

    Rather not:
    if foo == 'blah': do_blah_thing() do_one(); do_two(); do_three()</code></pre>

  • 虽然有时可以在 if/for/while 的同一行跟一小段代码,但绝不要对多条子句
    (multi-clause statements) 也这样做。也避免折叠这样的长行。

    <pre><code>最好不要 (Rather not):
    if foo == 'blah': do_blah_thing()
    for x in lst: total += x
    while t < 10: t = delay()

    明确不要 (Definitely not):
    if foo == 'blah': do_blah_thing()
    else: do_non_blah_thing()
    try: something()
    finally: cleanup()

    do_one(); do_two(); do_three(long, argument,
    list, like, this)
    if foo == 'blah': one(); two(); three()</code></pre>

注释

--(Comments)

--同代码不一致的注释比没注释更差,当代码修改时,始终优先更新注释;
--注释应该是完整的句子,如果注释是一个短语或句子,首字母应该大写,除非它是一 个以小写字母开头的标识符 (永远不要修改标识符的大小写);
--如果注释很短,可以省略末尾的句号,注释块通常由一个或多个段落组成,段落是由完整的句子构成的,每个句子应该以句号结尾;
--你应该在结束语句的句点 (a sentence-ending period) 后使用两个空格;
--用英语书写时,断词和空格是可用的 (When writing English, Strunk and White apply);;
--非英语国家的 Python 程序员:请用英语书写你的注释,除非你 120% 的确信代码永远不会被不懂你的语言的人阅读;
  • 块注释(Block Comments)

<pre>--注释块通常应用于跟随其后的一些 (或者全部) 代码,并和这些代码有着相同的缩进 层次。注释块中每行以 '#' 和一个空格开始
(除非它是注释内的缩进文本),注释块内的段落以仅含单个 '#' 的行分割;</pre>

  • 行内注释(Inline Comments)

<pre><code>节俭使用行内注释。
一个行内注释是和语句在同一行的注释,行内注释应该至少用两个空格和语句分开,它们应该以一个 '#' 和单个空格开始;
行内注释不是必需的,事实上,如果说的是显而易见事,还会使人分心,不要这样做:

x = x + 1 # Increment x

但是有时,这样是有益的:

x = x + 1 # Compensate for border</code></pre>

  • 文本字符串(Documentation Strings)

书写好的文档字符串 (又名"docstrings") 的约定,在 PEP 257中是永存的。

为所有公共模块、函数、类和方法书写文档字符串。文档字符串对非公开的方法不
是必要的,但你应该有一条注释来描述这个方法做什么;这条注释应该出现在 "def" 行之后。
PEP 257 描述了好的文档字符串约定。一定注意,多行文档字符串结尾的 """ 应该
单独成行,并推荐在其前加一空行,例如:
<pre><code>
"""Return a foobang
Optional plotz says to frobnicate the bizbaz first.
"""
对单行的文档字符串,结尾的 """ 在同一行也可以。</code></pre>

版本注记

--(Version Bookkeeping)

如果你用Subversion, CVS, or RCS管理你的代码文件, 可以参照下面的做法:

<pre><code>version = "$Revision$"

$Source$

这几行文字可以加在模块中文本字符串的后面,用空格与其余代码部分分开</code></pre>

命名惯例

--(Naming Conventions)

  • 首要原则(Overriding Principle)
    对公众可见的,如API中的命名,应当优先考虑名字反映其用途,而非应用;

  • 命名风格描述
    <pre><code>有许多不同的命名风格。以下的有助于辨认正在使用的命名风格,这独立于它们的作 用。
    以下的命名风格是众所周知的:

    • 单个小写字母 (b)
    • 单个大写字母 (B)
    • 小写串 (lowercase)
    • 带下划线的小写串 (lower_case_with_underscores)
    • 大写串 (UPPERCASE)
    • 带下划线的大写串 (UPPER_CASE_WITH_UNDERSCORES)
    • 首字母大写单词串 (CapitalizedWords) (或 CapWords、CamelCase -- 因其字母看起来错落有致,故得此名)。有时这也被称作StudlyCaps。
      注意: 在 CapWords 中使用缩写,需要把缩写的所有字母大写。故 HTTPServerError 比 HttpServerError 更好。
    • 混合大小写串 (mixedCase) (与首字母大写串不同之处在于第一个字符是小写的!)
    • 带下划线的首字母大写串 (Capitalized_Words_With_Underscores) (丑陋!)

    还有一种风格,使用特别的短前缀来将相关的名字分成组。这在 Python 中不常用, 但是出于完整性要提一下。例如,os.stat() 函数返回
    一个 tuple,其元素传统上有 象 st_mode, st_size, st_mtime 等等这样的名字。(这样做是为了强调与 POSIX 系 统调用结构体的相关
    性,这有助于程序员熟悉那些相关性。)X11 库的所有公开函数以 X 开头。在 Python 中,这个风格通常认为是不必要的,因 为属性和方法
    名以对象作前缀,而函数名以模块名作前缀。
    另外,以下用前导或后置下划线的特殊形式是被公认的 (通常这些可以和任何习惯相 组合):

    • single_leading_underscore:
      (单前导下划线): 弱的 "内部使用 (internal use)" 标志。 例如,"from M import " 不会导入以下划线开头的对象。
    • single_trailing_underscore:
      (单后置下划线): 习惯上用于避免与 Python 关键词的冲突。 例如: Tkinter.Toplevel(master, class='ClassName')
    • double_leading_underscore:
      (双前导下划线): 当用于命名 class 属性时,会触发名字重整 (name mangling)。 (在类 FooBar 中,boo 变成 FooBarboo;参加下面)。
    • double_leading_and_trailing_underscore:
      (双前导和后置下划线):存在于用户控制的 (user-controlled) 名字空间的 "magic" 对象或属性。例如: init, import or file 决不
      要发明这样的名字,仅像文档中那样使用即可。</code></pre>
  • 命名风格说明
    <pre><code>--避免采用的名字 (Names to Avoid)<pre><code>1 决不要用字符 'l' (小写字母 el),'O' (大写字母 oh),或 'I' (大写字母 eye) 作为单个字符的变量名。
    2 在一些字体中,这些字符不能与数字 1 和 0 区别开。当想要使用 'l' 时,用'L' 代替它。</code></pre>
    --包和模块名 (Package and Module Names)<pre><code>1 模块名应该是简短的、全部小写的名字。可以在模块名中使用下划线以提高可读性 。
    2 Python 包名也应该是简短的、全部小写的名字,尽管不推荐使用下划线。
    3 因为模块名被映射到文件名,有些文件系统大小写不敏感并且截短长名字,所以把 模块名选择为相当短就很重要了
    这在 Unix 上不是问题,但当把代码迁移到 Mac、Windows 或 DOS 上时,就可能是个问题了。当一个用 C 或 C++ 写的扩展模块,
    有一个伴随的 Python 模块来提供一个更高层 (例如,更面向对象) 的接口时,C/C++ 模块名有一个前导下划线 (如:socket)。</code></pre>
    --类名 (Class Names)<pre><code>几乎没有例外,类名使用首字母大写单词串 (CapWords) 的约定。 内部使用的类使用一个额外的前导下划线。</code></pre>
    --异常名 (Exception Names)<pre><code>因为异常应该是类,故类命名约定也适用于异常。然而,你应该对异常名添加后缀 "Error" (如果该异常的确是一个错误)。</code></pre>
    --全局变量名 (Global Variable Names)<pre><code>(让我们希望这些变量只打算用于一个模块内部。) 这些约定与那些用于函数的约定差不多。
    对设计为通过 "from M import " 来使用的模块,应采用 all 机制来防止导 出全局变量;或者使用旧的约定,为该类全局变量加一个前导下划线
    (可能你想表 明这些全局变量是 "module non-public")。</code></pre>
    --函数名 (Function Names)<pre><code>函数名应该为小写,必要时可用下划线分隔单词以增加可读性。
    混合大小写 (mixedCase) 仅被允许用于这种风格已经占优势的上下文 (如: threading.py),以便保持向后兼容。</code></pre>
    --函数和方法的参数 (Function and method arguments)<pre><code>1 对实例的方法,总是用 'self' 做第一个参数。
    2 对类的方法,总是用 'cls' 做第一个参数。
    如果函数的参数名与保留关键字冲突,在参数名后加一个下划线,比用缩写、错误 的拼写要好。因此 "print" 比 "prnt" 好。
    (也许使用同义词来避免冲突更好。)</code></pre>
    --方法名和实例变量 (Method Names and Instance Variables)<pre><code>1 采用函数命名规则:小写单词,必要时可用下划线分隔单词以增加可读性。
    2 仅对 non-public 方法和实例变量采用一个前导下划线。
    3 为避免与子类命名冲突,采用两个前导下划线来触发 Python 的命名重整规则。
    4 Python 用类名重整这些名字:如果类 Foo 有一个属性名为 a, 它不能以 Foo.a 访问。(执著的用户还是可以通过 Foo.Fooa 得到访问权。)
    通常,双 前导下划线仅被用来避免与基类的属性发生名字冲突。
    注:关于 names 的作用存在一些争论 (见下面)。</code></pre>
    --常量(Constants)<pre><code>常量通常是在模块级下定义并写入,常使用大写字母和下划线,其中下划线分隔单词。
    例子包括MAX_OVERFLOW和TOTAL。</code></pre>
    --继承的设计 (Designing for inheritance)<pre><code>1 总是确定类的方法和实例变量 (统称为属性) 是否应该被公开或者不公开。
    如果有 疑问,选择不公开;今后把其改为公开比把一个公开属性改为非公开要容易。
    2 公开属性是那些你期望你的类的不相关的客户使用,并根据你的承诺来避免向后不 兼容变更。非公开属性是那些确定不给第三方使用的;
    你不保证非公开属性不变,甚至被移除。这里我们不使用术语 "private",因为在 Python 中没有属性是真正私有的
    (没有 通常的无用功 (unnecessary amount of work))。
    3 另一类属性是 "subclass API" 的一部分 (在其他语言中通常称为 "protected")。 一些类被设计为基类,要么被扩展,要么类的某些行为被修改。
    当设计这样的类时,注意明确决定哪些属性是公开的,哪些是子类 API 的一部分,及哪些是真正仅被 你的基类使用。
    谨记这些 Python 特色的指导方针:
    公开属性应该没有前导下划线。
    如果公开属性名和保留关键字冲突,在你的属性名后添加一个后置下划线。这比
    缩写或者错误的拼写更可取。(然而,尽管这条规则,对任何已知是类的变量或者 参数,尤其是类方法的第一个参数,'cls' 是首选拼写方式。)
    注1:参见上面对类方法的参数名的建议。
    对简单的公开数据属性 (data attribute),最好只暴露属性名,没有复杂的访问
    /修改方法 (accessor/mutator methods)。谨记 Python 为将来增强提供了一条 容易的途径,
    你应该发现简单数据属性需要增加功能行为。在那种情况,
    用特性 (properties) 把功能实现隐藏在简单数据属性访问语法后面。
    注1:特性仅工作于 new-style 的类。
    注2:尝试不管功能行为的副作用,尽管像 cache 之类副作用通常是好的。
    注3:避免对费时的计算操作使用特性;属性符号使调用者相信访问是 (相对)
    廉价的。
    如果确定你的类会被子类化,并且你有不希望子类使用的属性,考虑用两个前导
    下划线、但没有后置下划线命名它们。这将触发 Python 的名字重整算法,把类 名整合进属性名中。当子类无意中包含了相同名字的属性时,
    这有助于避免属性 名冲突。
    注1:注意仅使用简单类名来重整名字,因此,如果子类使用相同的类名和属性名
    ,你仍然会名字冲突。
    注2:名字重整使一些应用稍有不便,例如调试和 getattr()。然而名字重整
    算法有良好的文档,也容易手工执行。
    注3:不是每个人都喜欢名字重整。尝试在避免意外的名字冲突需求和高级调用者
    的可能应用之间平衡。</code></pre>
    </code></pre>

编程建议

--(Programming Recommendations)

代码应该按照一种方式编写,但是不应该不利于在其他python中的应用 (PyPy, Jython, IronPython, Cython, Psyco, and such).

例如,对 a+=b or a=a+b 形式的语句,不要依赖 CPython 对就地 (in-place) 字 符串连接的高效实现。那些语句在 Jython 中运行很慢。对库的性能敏感部分,应 该改用 ''.join() 语句。这将保证对不同的实现,字符串连接表现为线性时间。

与 None 之类的单件比较,应该总是用 'is' or 'is not',绝不要用等号操作符。

同样,当你本意是 "if x is not None" 时,对写成 "if x" 要小心 -- 例如,当 测试一个默认为 None 的变量或参数是否被设置为其他值时,这个其他值可能是一种 在布尔上下文中为假的类型 (例如容器)!

使用is not而不是not ... is,虽然两者表述的功能相同,但是前者的可读性和钟爱度更高

<pre><code>Yes:

if foo is not None:
No:

if not foo is None:</code></pre>

当使用一些比较的操作命令时,最好能够用以下6中操作( eq , ne , lt , le , gt , ge ) 而不是依赖其他的一些比较方法。

为了减小关联性,functools.total_ordering()提供生成了一些缺失的比较方法。

PEP 207假定Python具有自反性,因此解释器可能交换 y > x 成 x < y , y >= x 成 x <= y , 又或者把 x == y 转换成 x != y。sort() 与min()操作是基于 < 运算符,max()函数使用 > 运算符。然而, 最好是使用上述的六种方式,这样不会增加在其他文本中的混淆。

使用def-statement比绑定一个lambda表达式的assignment-statement要好

<pre><code>Yes:

def f(x): return 2*x
No:

f = lambda x: 2*x</code></pre>

other example

<pre><code>Yes:

try:
value = collection[key]
except KeyError:
return key_not_found(key)
else:
return handle_value(value)
No:

try:
# Too broad!
return handle_value(collection[key])
except KeyError:
# Will also catch KeyError raised by handle_value()
return key_not_found(key)</code></pre>

<pre><code>Yes:

with conn.begin_transaction():
do_stuff_in_transaction(conn)
No:

with conn:
do_stuff_in_transaction(conn)</code></pre>

<pre><code>Yes:

def foo(x):
if x >= 0:
return math.sqrt(x)
else:
return None

def bar(x):
if x < 0:
return None
return math.sqrt(x)
No:

def foo(x):
if x >= 0:
return math.sqrt(x)

def bar(x):
if x < 0:
return
return math.sqrt(x)</code></pre>

<pre><code>Yes: if foo.startswith('bar'):
No: if foo[:3] == 'bar':
Object type comparisons should always use isinstance() instead of comparing types directly.</code></pre>

<pre><code>Yes: if isinstance(obj, int):

No: if type(obj) is type(1):</code></pre>

<pre><code>Yes: if not seq:
if seq:

No: if len(seq)
if not len(seq)</code></pre>

<pre><code>Yes: if greeting:
No: if greeting == True:
Worse: if greeting is True:</code></pre>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容