PEP8中文版 -- Python编码风格指南(中)

Python部落组织翻译, 禁止转载

字符串引号


Python中,单引号字符串和双引号字符串是一样的。本PEP不建议如此。建议选择一条规则并坚持下去。当一个字符串包含单引号字符或双引号字符时,使用另一种字符串引号来避免字符串中使用反斜杠。这提高可读性。

三引号字符串,与PEP 257 文档字符串规范一致总是使用双引号字符。


表达式和语句中的空格


无法忍受的


以下情况避免使用多余的空格:


紧挨着小括号,中括号或大括号。

风格良好:spam(ham[1], {eggs: 2})
风格不良:spam( ham[ 1 ], { eggs: 2 } )

紧挨在逗号,分号或冒号前:

风格良好: if x == 4: print x, y; x, y = y, x
风格不良: if x == 4 : print x , y ; x , y = y , x

在切片中冒号像一个二元操作符,冒号两侧的有相等数量空格(把它看作最低优先级的操作符)。在一个扩展切片中,两个冒号必须有相等数量的空格。例外:当一个切片参数被省略时,该空格被省略。

风格良好:

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]
风格不良:
ham[lower + offset:upper + offset]
ham[1: 9], ham[1 :9], ham[1:9 :3]
ham[lower : : upper]
ham[ : upper]

紧挨着左括号之前,函数调用的参数列表的开始处:

风格良好:spam(1)
风格不良:spam (1)

紧挨着索引或切片开始的左括号之前:

风格良好:dct['key'] = lst[index]
风格不良:dct ['key'] = lst [index]

为了与另外的赋值(或其它)操作符对齐,不止一个空格。

风格良好:
x = 1
y = 2
long_variable = 3
风格不良:
x             = 1
y             = 2
long_variable = 3

其它建议


始终在这些二元操作符的两边放置一个空格:赋值(= ),增强赋值(+= ,-= 等),比较(== , < , > , != , <> , <= , >= ,in , not in ,is ,is not ),布尔(and ,or ,not )。
如果使用了不同优先级的操作符,在低优先级操作符周围增加空格(一个或多个)。不要使用多于一个空格,二元运算符两侧空格数量相等。

风格良好:
i = i + 1
submitted += 1
x = x*2 - 1
hypot2 = x*x + y*y
c = (a+b) * (a-b)
风格不良:
i=i+1
submitted +=1
x = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)

当=符号用于指示关键字参数或默认参数值时,它周围不要使用空格。

风格良好:
def complex(real, imag=0.0):
    return magic(r=real, i=imag)
风格不良:
def complex(real, imag = 0.0):
    return magic(r = real, i = imag)

带注解的函数定义的=符号周围使用空格。
另外,:后使用一个空格,->前后各使用一个空格代表一个带注解的返回值。

风格良好:
def munge(input: AnyStr):
def munge(sep: AnyStr = None):
def munge() -> AnyStr:
def munge(input: AnyStr, sep: AnyStr = None, limit=1000):
风格不良:
def munge(input: AnyStr=None):
def munge(input:AnyStr):
def munge(input: AnyStr)->PosInt:

不鼓励使用复合语句(同一行有多条语句)。

鼓励的:
if foo == 'blah':
    do_blah_thing()
do_one()
do_two()
do_three()
最好不要:
if foo == 'blah': do_blah_thing()
do_one(); do_two(); do_three()

尽管有时if/for/while的同一行跟一小段代码,在一个多条子句的语句中不要如此。避免折叠长行!

最好不要:
if foo == 'blah': do_blah_thing()
for x in lst: total += x
while t < 10: t = delay()
绝不要:
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()


注释


同代码相矛盾的注释比没有注释更差。当代码修改时,始终优先更新注释!

注释应该是完整的句子。如果注释是一个短语或句子,它的第一个单词的首字母应该大写,除非它是一个以小写字母开头的标识符(不更改标识符的情况下!)。

如果注释很短,末尾可以不加句号。注释块通常由一个或多个段落组成,这些段落由完整的句子组成,并且每个句子都应该以句号结尾。

在句尾的句号后边使用两个空格。

写英语注释时,遵循断词和空格。

非英语国家的Python程序员:请用英语书写注释,除非你120%的确定,所有看你代码的人都和你说一样的语言。

非英语国家的Python程序员:请写下你的意见,在英语中,除非你是120%肯定,代码将不会被不讲你的语言的人阅读。
注释块
注释块通常适用于一些(或全部)紧跟其后的代码,并且那些代码应使用相同级别的缩进。注释块的每行以一个#和一个空格开始(除非注释里面的文本有缩进)。

注释块内的段落之间由仅包含#的行隔开。


行内注释


谨慎地使用行内注释。

行内注释就是注释和代码在同一行,它与代码之间至少用两个空格隔开。并且它以#和一个空格开始。

如果行内注释指出的是显而易见,那么它就是不必要的。  不要这样做:
x = x + 1                 # 增加 x
但有时,这样是有用的:
x = x + 1                 # 补偿border


文档字符串


编写好的文档字符串(即“代码”)约定在PEP 257中是永存的。

为所有公共模块,函数,类和方法书写文档字符串。对非公开的方法书写文档字符串是没有必要的,但应该写注释描述这个方法是做什么的。这些注释应该写在def行后面。
PEP 257描述了好的文档字符串约定。最重要的是,多行文档字符串以一行"""结束,例如:
"""Return a foobang

Optional plotz says to frobnicate the bizbaz first.
"""
对于只有一行的文档字符串,"""同一行上。


版本注记


如果你不得不将Subversion,CVS,或RCS包含在你的源文件中,按如下做。
__version__ = "$Revision$"
# $Source$
这些行包括在模块的文档字符串之后,任何其它代码之前,上下各用一个空行分开。


命名规范


Python库的命名规范有点儿混乱,所以我们不会将他们变得完全一致——不过,这是目前推荐的命名标准。新模块和包(包括第三方框架)应该按这些标准书写,但对有不同的风格的已有库,保持内部一致性是首选。


根本原则


用户可见的API的公开部分的名称,应该遵循反映用法而不是实现的约定。


描述:命名风格


有很多不同的命名风格。它有助于识别使用了什么样的命名风格,这独立于他们的作用。

下面的命名风格是最常见的:

  • b(单个小写字母)

  • B(单个大写字母)

  • 小写字符串

  • 带下划线的小写字符串

  • 大写字符串

  • 带下划线的大写字符串

  • 首字母大写的字符串(或CapWords,或驼峰命名法——因其字母看起来高低不平而得名[3])。这有时也被称为StudlyCaps。

   注意:当CapWords中使用缩写,大写所有的缩写字母。因此HTTPServerError优于HttpServerError。

  • 混用大小写的字符串(与首字母大写字符串不同的是它以小写字母开头)

  • 带下划线的首字母大写字符串(令人厌恶的!)


还有一种风格,使用简短独特的前缀组织相关的名字在一起。Python中很少这样用,提一下是为了文档的完整性。例如,os.stat()函数返回一个元祖,它的元素名字通常类似st_mode,st_size,st_mtime等等这样。(这样做是为了强调与POSIX系统调用结构体一致,这有助于程序员熟悉这些。)

X11库的所有的公开函数以X开头。Python中,这种风格通常认为是不必要的,因为属性名和函数名以对象名作前缀,而函数名以模块名作前缀。


另外,以下特殊形式,前导或后置下划线是公认的(一般可以与任何约定相结合):

  • 单前导下划线:弱“内部使用”标志。例如 from M import *不会导入以下划线开头的对象。

  • 单后置下划线:按惯例使用避免与Python关键字冲突,例如。

     Tkinter.Toplevel(master, class_='ClassName')

  • 双前导下划线:当命名类属性,调用时名称改编(类FooBar中,__boo变成 _FooBar__boo;见下文)。

  • 前导和后置都是双下划线:存在于用户控制的命名空间的“神奇”的对象或属性。

    例如:__init__,__import__或__file__。不要创造这样的名字;仅像文档中那样使用他们。


规定:命名约定


避免采用的名字


不要使用字符‘l’(小写字母el),‘O’(大写字母oh)或‘I’(大写字母eye)作为单字符变量名。

在某些字体中,这些字符与数字1和0是没有区别的。当想使用‘l’时,用‘L’代替。


包名和模块名


模块名应该短,所有的字母小写。可以在模块名中使用下划线来提高可读性。Python包名也应该短,所有的字母小写,不鼓励使用下划线。

当一个C或C++书写的扩展模块,伴随Python模块来提供了一个更高层次(例如更面向对象)的接口时,C/C++模块名有一个前导下划线(如_socket)。


类名


类名通常使用首字母大写字符串的规则。

函数的命名规则  主要用来可调用的。

在接口被记录并且主要用作调用的情况下,用函数的命名规则来代替类名的命名规则。

注意内置名有一个单独的规则:大多数的内置名是一个单词(或两个单词一起),首字母大写字符串的规则仅用于异常名和内置常量。


异常名


因为异常应该是类,所以类的命名规则在这里也同样适用。然而,异常名(如果这个异常确实是一个错误)应该使用后缀“Error”。
全局变量名(希望这些变量是在一个模块内使用。)这些规则和那些有关函数的规则是相同的。

模块设计为通过from M import *来使用,应使用__all__机制防止导出全局变量,或使用加前缀的旧规则,为全局变量加下划线(可能你像表明这些全局变量是“非公开模块”)。


函数名


函数名应该是小写字母,必要时单词用下划线分开以提高可读性。

混合大小写仅用于这种风格已经占主导地位的上下文(例如threading.py),以保持向后兼容性。


函数和方法参数


使用self做实例化方法的第一个参数。

使用cls做类方法的第一个参数。

如果函数的参数名与保留关键字冲突,最好是为参数名添加一个后置下划线而不是使用缩写或拼写错误。

因此class_ 比clss好。(也许使用同义词来避免更好。)。


方法名和实例变量


采用函数命名规则:小写字母,必要时单词用下划线分开以提高可读性。

仅为非公开的方法和实例变量使用一个前导下划线。

为了避免和子类命名冲突,使用两个前导下划线调用Python的名称改编规则。

Python用类名改编这些名字:如果类Foo有一个属性名为__a,通过Foo.__a不能访问。(可以通过调用Foo._Foo__a来访问。)通

常,两个前导下划线仅用来避免与子类的属性名冲突。

注意:关于__names的使用存在一些争论(见下文)。


常量


常量通常定义于模块级别并且所有的字母都是大写,单词用下划线分开。例如MAX_OVERFLOW和TOTAL。


英文原文: https://www.python.org/dev/peps/pep-0008/

译者: wangyc
 

2月15日11:00到13:00网站停机维护,13:00前恢复