1. 呆板的坚持使用一致性是傻得没边!(A Foolish Consistency is the Hobgoblin of Little Minds)

  2. 打破一条既定规则的两个好理由: a. 当应用这个规则是将导致代码可读性下降,即便对某人来说,他已经习惯于按这条规则来阅读代码了。

b. 为了和周围的代码保持一致而打破规则(也许是历史原因)

  1. 代码布局 a. 缩进 使用Emacs的Python-mode的默认4个空格。

永远不要混用制表符和空格,最流行的方式是采用空格,其次是使用制表符。混合空格和制表符的代码将被转换成空格。(Emacs中,选中整个缓冲区,按ESC-x去除制表符(untabilfy))。调用Python解释器时-t选项,可对混合制表符和空白的发出警告,-tt时警告将变成错误。

b. 行 将行限制在79个字符,对顺序排放的大文本块或者注释推荐限制在72个字符。

折叠长行的首选方法是使用Python支持的圆括号,方括号和花括号内的行延续。如果需要你可以在表达式周围增加一对额外的圆括号,但有时使用反斜杠看起来更好。

c. 空行

用两行空行分割顶层函数和类的定义,类内方法的定义使用单个行分割,额外的空行可被用于相关函数组成的群。在一组相关的单句中间可以省略空行。

当空行用于分割方法的定义时,在’class’行和第一个方法定义之间也需要一个空行。

在函数中使用空行时,表示一个逻辑段落。

Python接受Ctrl+L换页符作为空格,Emacs和一些打印工具视这个为分页符。因此可以在代码中用它来为相关代码片段分页。

  1. 编码 Python核心发布中的代码必须始终使用ASCII或Latin=1(ISO-8859-1).使用ASCII的文件不必有译码cookie(coding cookie)。Latin-1公当注释或文档字符串涉及作者名字需要Latin-1时才被使用;另外\x转义字符是在字符串中包含非ASCII数据的首选方法。

Python 2.4以后内核支持Unicode。

不论什么情况使用UTF-8吧!

  1. 导入 通常应该在单独的行中导入,例如:
1
2
3
No:	import sys, os
Yes:	import sys
	import os

但是这样也是可以的:

1
	from type import StringType, ListType

Imports通常被放置在文件的顶部,仅在模块注释和文档字符串之后,在模块的全局变量和常量之前。Imports应该有顺序的成组放置:

a. 标准库的导入

b. 相关的主包的导入

c. 特定应用的导入

应该在每组导入之间放置一个空行

对于内部包的导入是不推荐使用相对导入,所有的导入都应使用包的绝对路径

从一个包含类的模块中导入类时,通常可以写成

1
2
from MyClass import MyClass
from foo.bar.YourClass import YourClass

如果这样写导致了本地名字冲突,就写成:

1
2
import MyClass
import foo.bar.YourClass import YourClass

即使用"MyClass.MyClass"和"foo.bar.YourClass.YourClass"

  1. 空格 Guido不喜欢在以下地方出现空格:

a. 紧挨着圆括号、方括号、花括号的

b. 紧贴在逗号、分号、冒号前的

c. 紧贴着函数调用的参数列表前开式括号的,如"spam (1)“要写成"spam(1)”

d. 紧贴在索引或切片开始的开式括号前的

e. 在赋值(或其它)运算符周围的用于和其它并排的一个以上的空格

  1. 其它建议 a. 始终在这些二元运算符两边放置一个空格:=,==,<,>,!=,<>,<=,>=,is,is not,in,not in布尔运算符and,or,not。

b. 按你的看法在算术运算符周围插入空格,始终保持二元运算符两边空格的致。

c. 不要在用于指定关键字参数或默认参数值的"=“周围使用空格。

e. 不要将多条语句写在同一行上

  1. 注释 a. 同代码不一致的注释比没注释更差,当代码修改时,始终优先更新注释。

b. 注释应该是完整的句子。如果注释是一个句子或短语,首字母应该大写,除非是一个小写开头的标识符(永远不要修改标识符的大小写)。

c. 如果注释很短,最好省略末尾的句号。注释块通常由一个或多个完整句子构成的段落组成。每个句子应该以句号结束。

d. 应该在句末,句号后使用两个空格,以便Emacs的断行和填充工作能正常工作。”.“给出了文档结构的提示

e. 用英语书写时,断词和空格是可用的。

f. 非英语国家的Python程序员,请使用英语写你的注释,除非你120%的确信,这些代码不会被不懂你语言的人阅读。

g. 编写使用统一的文档化注释格式有得于良好习惯和团队建议!

  1. 注释块 a. 注释块通常应用于跟随着一些(或全部)代码并和这些代码有着相同的缩进层次。注释块中每行以#和一个空格开始。注释块中的段落以仅含单个#的行分割,注释块上下方最好有一空行包围(或上方两行下方一行,对一个新函数定义段的注释。

  2. 行内注释 一个行内注释是和语句在同一行的注释,行内注释应该谨慎使用。行内注释应该至少用两个空格和语句分开,它们应该以#和单个空格开始。

  3. 文档化 应该一直遵守编写好的文档字符串(docstring)的约定。 为所有公共模块、函数、类和方法编写文档字符串。文档字符串对非公开的方法不是必要的,但你应该有一个描述这个方法做什么的注释,这个注释应该在"def"这个行后

多行文档字符串最后的”"",应该单独成行。

单行文档字符串最后的""",可以在同一行。

  1. 版本标记 例:
1
2
__version__=="$Revision: 1.4$"
# $Source: E:/cvsroot/python_doc/pep8.txt,v$

这个行应该包含在模块的文档字符串之后,所有代码之前,上下用一个空行分隔。

  1. 命名约定 应该避免的名字

永远不要用字符’l',‘O’,或’I’作单字符的变量名。在某些字体中,这些字符不能与数字1和0分开,当然要使用’l’时,使用’L’代替它。

  1. 模块名 模块应该是不含下划线的、 简短的、小写的名字。

因为模块名被映射到文件名,有些文件系统大小写不敏感并且截短长名字,模块名被选为相当短是重要的。

当一个用C或C++写的扩展模块有一个伴随的Python模块,这个Python模块提供了一个更高层的接口时,C/C++模块有一个前导下划线。

Python包应该是不含下划线的、简短的、全小写的名字。

  1. 类名 类名总是使用首字母大写单词串的约定。

  2. 异常名 如果模块对所有情况定义了单个异常,它通常被叫做"error"或"Error"。似乎内建(扩展)模块使用"error",而Python模块通常用"Error",趋势似乎是倾向于使用CapWords异常名。

  3. 全局变量名 让我们希望这些变量打算只被用于模块内部,这些约定与那些用于函数的约定差不多,被设计为可以通过"from M import *“来使用的那些模块,应该在那些不想被导入的全局变量(还有内部函数和类)前加一个下划线。

  4. 函数名 函数名应该为小写,可能用下划线风格单词可以增加可读性。mixedCase仅被允许用于这种风格已经占优势的上下文,以便保持向后兼容。

  5. 方法名称和实例变量 这段大体和函数相同,通常用小写,必要时使用下划线。

使用一个前导下划线仅用于不打算作为类的公共接口的内部方法和实例变量。

使用两个前导下划线以表示类私有的名字。通常双前导下划线应该只用来避免与类(可以为子类化所设计)中的属性发生名字冲突。

  1. 继承的设计 始终要确定一个类中的方法和实例变量是否要被公开,通常,永远不要将数据变量公开,除非你本质上实现的只是记录,人们总是共喜欢给类提供一个函数的接口作为替换。

同样,确定你的属性是否应该为私有的,私有的与非私有的区别在于:前者永远不会被用在一个派生类中,而后者可能会。是的,你应该在大脑中就用继承设计好了你的类。

私有属性必须有两个前置下划线,无后置下划线。

非公有属性必须有一个前导下划线,无后置下划线。

公共属性没有前导和后置下划线,除非它们与保留字冲突,在这种情况下,单个后置下划线比前置或混乱的拼写要好,例如:class_比klass好。

  1. 设计建议

同象None之类的单值进行比较,应该永远用:‘is’或’is not’来做,当你本意是"if x is not None时,对写成"if x"要小心--例如当你测试一下默认值为None的变量或参数是否被设置为其它值时,这个其它值也可能是一个在布尔上下文中为假的值!

基于类的异常总是好过基于字符串的异常,模块和包应该定义它们自己的域内特定的基异常类(base exception class),基类应该是内建的Exception类的子类,还始终包含一个类的的文档字符串,例如:

1
2
class MessageError(Exception):
      """Base class for errors in the email package."""

使用字符串方法代替字符串模块,除非必须向后兼容Python2.0以前的版本。字符串方法总是非常快,而且和unicode字符串共用同样的API。

在检查前缀和后缀时避免对字符串进行切片。

用startswith()和endswith()代替,因为它们是明确的并且错误更少,例如:

1
2
No: if foo[:3] == 'bar':
Yes: if foo.startswith('bar'):

例外是如果你的代码必须工作在Python1.5.2以前。

对象类型的比较应该始终用isinstance()代替直接比较类型。

1
2
No: if type(obj) is type(1):
Yes: if isinstance(obj,int):

检查一个对象是否是字符串时,谨记它也可能是unicode字符串!在Python2.3,str和unicode有公共的基类,basestring,所以你可以这样做:

1
if isinstance(obj,basestring)

Python2.2类型模块为此定义了StringType类型。

对序列,(字符串(strings),列表(lists),元组(tuple))使用空列表是false这个事实,因此"if not seq"或"if seq"比"if len(seq)“或"if not len(seq)“好。

书写字符串文字时不要依赖于有意义的的后置空格,这种后置空格在视觉上是不可辩别的,并且有些编辑器会把它们修整掉。

不要用==来比较布尔型的值以确定是True或False。