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

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

目录
      缩进
      制表符仍是空格?
      行的最大长度
      空行
      源文件编码
      导入
      没法忍受的
      其它建议
      注释块
      行内注释
      文档字符串
      根本原则
      描述:命名风格
      规定:命名约定程序员

 

算法

 

本文档所提供的编码规范,适用于主要的Python发行版中组成标准库的Python代码。请参阅PEP关于Python的C实现的C编码风格指南的描述[1]。

本文档和PEP257(文档字符串规范)改编自Guido的《Python Style Guide》一文,用Barry的风格指南[2]作一些补充。

这篇风格指南随着时间的推移而逐渐演变,随着语言自己的变化,过去的约定已通过时了并肯定了更多新的约定。

许多项目都有本身的编码风格指南。若是有任何冲突,优先使用该项目特定的指南。编程

 

使人讨厌的小人物身上愚蠢的一致性缓存

 

Guido的一个重要的看法是,代码阅读的次数比编写的次数多。这里提供的指南旨在提升代码的可读性,并使各类不一样的Python代码一致。如PEP20所说,“易读性很是重要”。

风格指南是关于一致性的。与本风格指南一致很重要。项目中的一致性更重要。一个模块或功能中的一致性最重要。

最重要的是:知道什么时候会不一致——有时风格指南就不适用了。怀疑时,做出你最佳的判断。看看其余的例子,并决定什么是最好的。不要犹豫,尽管发问!

特别地:不要只为听从这个PEP而打破向后兼容性!

忽视既定指南的一些其余的好理由:
一、当应用指南会下降代码的可读性,即便对于那些习惯遵守这个PEP来阅读代码的人来讲。
二、与周围的代码保持一致也会破坏它(多是历史缘由)——虽然这也是收拾别人烂摊子的好机会(在真正的XP风格中)。
三、由于问题代码先于指南,又没有其它的修改理由。
四、代码须要兼容老版本,本风格指南不建议使用的Python特性。网络

 

代码布局数据结构

 

缩进框架

 

每级缩进使用4个空格。
连续行应该对齐折叠元素,不管是垂直的Python的隐式行链接圆括号内的,中括号内的,大括号内的,仍是使用悬挂缩进[5]。使用悬挂缩进应注意如下几点;socket

 

第一行没有参数而且使用更多的缩进来区别它自己和连续行。编辑器

 

风格良好:

article4.png


风格不良:

article4.png


对于连续行,4个空格规则是可选的。
可选的:
article4.png


if语句条件块足够长时须要编写多行,值得注意的是两个字符组成的关键字(例如if),加上一个空格,加上开括号为多行条件的后续行建立一个4个空格的缩进。这能够给嵌入if内的缩进语句产生视觉冲突,这也天然被缩进4个空格。这个PEP没有明确如何(是否)进一步区分条件行和if语句内的嵌入行。这种状况下,能够接受的选项包括,但不只限于:

article4.png


多行结构中的结束花括号/中括号/圆括号是最后一行的第一个非空白字符,如:

article4.png

或者是最后一行的第一个字符,如:

article4.png

 

制表符仍是空格?

 

空格是缩进方法的首选。
制表符仅用于与已经用制表符作缩进的代码保持一致。
Python3不容许混用制表符和空格来缩进。
Python2代码混用制表符和空格缩进,将被转化为只使用空格。
调用Python2命令行解释器时使用-t选项,可对代码中非法混用制表符和空格发出警告。当使用-tt选项,警告将变成错误。这些选项是高度推荐的!

 

行的最大长度


限制全部行最多79个字符。

下垂的长块结构限制为更少的文本(文档字符串或注释),行的长度应该限制在72个字符。

限制编辑器窗口宽度使得并排打开多个文件成为可能,而且使用代码审查工具显示相邻列的两个版本工做正常。

绝大多数工具的默认折叠会破坏代码的可视化结构,使其更难以理解。编辑器中的窗口宽度设置为80个字符。即便该工具将在最后一列中标记字形。一些基于网络的工具可能不会提供动态的自动换行。

有些团队强烈喜欢较长的行长度。对于代码维护彻底或主要由一个团队的,能够在这个问题上达成协议,象征性的将行长度从80个字符增长到100个字符(有效地增长最大长度到99个字符)也是能够的,提供注释和文档字符串还是72个字符。

Python标准库采起保守作法,要求行限制到79个字符(文档字符串/注释到72个字符)。

折叠长行的首选方法是在小括号,中括号,大括号中使用Python隐式换行。长行能够在表达式外面使用小括号来变成多行。连续行使用反斜杠更好。

反斜杠有时可能仍然是合适的。例如,长的多行的with语句不能用隐式续行,能够用反斜杠:

article4.png

(为进一步思考With语句的多行缩进,见前面多行if语句的讨论。)


另外一个这样的例子是assert语句。

确保适当的连续行缩进。

 

换行应该在二元操做符的前面仍是后面?

 

过去二十年咱们都是推荐放在二元操做符的后面。可是这种作法会以两种方式伤害可读性:多个二元操做符在屏幕上不在一列,另外若是你想知道对一个被操做的对象作了什么操做,须要向上找一行。这致使你的眼睛不得不上下往返不少次才能搞清楚哪一个数字是被加的,哪一个数字是被减的:

article4.png

为了解决可读性问题,数学家和印刷业者一般是在二元操做符以前换行的。Donald Knuth在他的《计算机与排版》系列文章中解释了这个传统规则:“虽然写在一段话中的公式常常在二元操做符的后面换行,可是单独展现的公式一般是在二元操做符的前面换行。”

出于遵循数学传统,因此咱们这样写这段代码将更加可读:

article4.png

 

空行

 

顶级函数和类的定义之间有两行空行。

类内部的函数定义之间有一行空行。

额外的空行用来(谨慎地)分离相关的功能组。相关的行(例如:一组虚拟实现)之间不使用空行。

在函数中谨慎地使用空行来表示逻辑部分。

Python接受control-L(即^L)换页符做为空白符;许多工具把这些字符做为分页符,因此你可使用它们为文件中的相关部分分页。注意,一些编辑器和基于Web的代码查看器可能不能识别control-L是换页,将显示另外的字形。

 

源文件编码

 

Python核心发布中的代码应该始终使用UTF-8(或Python2中用ASCII)。
文件使用ASCII(Python2中)或UTF-8(Python3中)不该有编码声明。

在标准库中,非默认编码仅用于测试目的或注释或文档字符串须要说起包含非ASCII字符的做者名;不然,使用\x,\u,\U,或\N是字符串中包含非ASCII数据的首先方式。

Python3.0及以上版本,为标准库(参见PEP 3131)规定如下策略:Python标准库中的全部标识符必须使用ASCII标识符,在可行的地方使用英文单词(在不少例子中,使用非英文的缩写和专业术语)。另外,字符串和注释必须用ASCII。仅有的例外是(a)测试非ASCII的特色,(b)测试做者名。不是基于拉丁字母表的做者名必须提供一个他们名字的拉丁字母表的音译。

开源项目面向全球,鼓励采用统一策略。

 

导入

 

导入一般是单独一行,例如:
风格良好:

article4.png


风格不良:

article4.png

 

这样也是能够的:

article4.png


导入经常位于文件顶部,在模块注释和字符串文档以后,在模块的全局变量和常量以前。

导入应该按照如下顺序分组:
1. 标准库导入
2. 相关的第三方导入
3. 特定的本地应用/库导入
在每一个导入组之间放一行空行。

把任何相关__all__规范放在导入以后。
推荐绝对导入,由于它们更易读,而且若是导入系统配置的不正确(例如当包中的一个目录结束于sys.path)它们有更好的表现(至少给出更好的错误信息):
article4.png
明确的相对导入能够用来接受替代绝对导入,特别是处理复杂包布局时,绝对导入过于冗长。
article4.png
标准库代码应该避免复杂包布局并使用绝对导入。
隐式的相对导入应该永远不被使用,而且在Python3中已经移除。
从一个包含类的模块中导入类时,一般下面这样是好的写法:
article4.png

若是这种写法致使本地名字冲突,那么就这样写:
article4.png

并使用“myclass.MyClass”和“foo.bar.yourclass.YourClass”来访问。
避免使用通配符导入(from <模块名> import *),由于它们使哪些名字出如今命名空间变得不清楚,这混淆了读者和许多自动化工具。通配符导入有一种合理的使用状况,从新发布一个内部接口做为一个公共API的一部分(例如,重写一个纯Python实现的接口,该接口定义从一个可选的加速器模块而且哪些定义将被重写提早并不知道)。

用这种方式从新命名,下面的有关公共和内部接口的指南仍适用。

 

模块级别的内置属性

 

模块级别的内置属性(名字有先后双下划线的),例如__all__, __author__, __version__,应该放置在模块的文档字符串后,任意import语句以前,from __future__导入除外。Python强制要求from __future__导入必须在任何代码以前,只能在模块级文档字符串以后。

article4.png

 

字符串引号

 

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

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

 

表达式和语句中的空格

 

没法忍受的

 

如下状况避免使用多余的空格:

 

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

article4.png

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

article4.png

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

article4.png

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

article4.png

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

article4.png

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

article4.png

 

其它建议

 

始终避免行尾空白。由于它们一般不可见,容易致使困惑:若是\后面跟了一个空格,它就不是一个有效的续行符了。不少编辑器不保存行尾空白,CPython项目中也设置了commit前检查以拒绝行尾空白的存在。

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

article4.png

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

article4.png

带注解的函数使用正常的冒号规则,而且在->两侧增长一个空格:

article4.png

若是参数既有注释又有默认值,在等号两边增长一个空格(仅在既有注释又有默认值时才加这个空格)。

article4.png

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

article4.png

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

article4.png

 

何时使用尾部逗号?

 

尾部逗号一般都是可选的,除了一些强制的场景,好比元组在只有一个元素的时候须要一个尾部逗号。为了代码更加清晰,元组只有一个元素时请务必用括号括起来(语法上没有强制要求):

article4.png

当尾部逗号不是必须时,若是你用了版本控制系统那么它将颇有用。当列表元素、参数、导入项将来可能不断增长时,留一个尾部逗号是一个很好的选择。一般的用法是(好比列表)每一个元素独占一行,而后尾部都有逗号,在最后一个元素的下一行写闭标签。若是你的数据结构都是写在同一行的,就没有必要保留尾部逗号了。

article4.png

 

注释

 

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

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

若是注释很短,末尾能够不加句号。注释块一般由一个或多个段落组成,这些段落由完整的句子组成,而且每一个句子都应该以句号结尾。

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

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

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

非英语国家的Python程序员:请写下你的意见,在英语中,除非你是120%确定,代码将不会被不讲你的语言的人阅读。

 

注释块

 

注释块一般适用于一些(或所有)紧跟其后的代码,而且那些代码应使用相同级别的缩进。注释块的每行以一个#和一个空格开始(除非注释里面的文本有缩进)。

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

 

行内注释

 

谨慎地使用行内注释。

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

若是行内注释指出的是显而易见,那么它就是没必要要的。  不要这样作:
article4.png

但有时,这样是有用的:
article4.png

 

文档字符串

 

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

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

对于只有一行的文档字符串,"""同一行上。

 

命名规范

 

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)。

 

类名

 

类名一般使用首字母大写字符串的规则。

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

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

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

 

类型变量名称

 

类型变量名称应该首字母大写,而且尽可能短,好比:T, AnyStr, Num。对于协变量和有协变行为的变量,建议添加后缀__co或者__contra。

article4.png

 

异常名

 

由于异常应该是类,因此类的命名规则在这里也一样适用。然而,异常名(若是这个异常确实是一个错误)应该使用后缀“Error”。

 

全局变量名

 

(但愿这些变量是在一个模块内使用。)这些规则和那些有关函数的规则是相同的。

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

 

 

函数名

 

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

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

 

函数和方法参数

 

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

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

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

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

 

方法名和实例变量

 

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

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

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

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

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

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

 

常量

 

常量一般定义于模块级别而且全部的字母都是大写,单词用下划线分开。例如MAX_OVERFLOW和TOTAL。

 

继承的设计


肯定类的方法和实例变量(统称为:“属性”)是否公开。若是有疑问,选择非公开;以后把其变成公开比把一个公开属性改为非公开要容易。

公开属性是那些你指望与你的类不相关的客户使用的,根据你的承诺来避免向后不兼容的变动。非公开属性是那些不打算被第三方使用的;你不保证非公开属性不会改变甚至被删除。

非公共属性是那些不打算被第三方使用的,你不能保证非公开的属性不会改变甚至被删除。

此处没有使用术语“private”,由于Python中没有真正私有的属性(没有一般的没必要要的工做)。

属性的另外一个类别是“API子集”的一部分(在其它语言常被称为“protected”)。某些类被设计为基类,要么扩展,要么修改某些方面的类的行为。在设计这样的类的时候,要注意明确哪些属性是公开的,哪些是API子类的一部分,哪些是真正只在你的基类中使用。


清楚这些以后,这是Python特点的指南:

  • 公开属性没有前导下划线。

  • 若是公开属性名和保留关键字冲突,给属性名添加一个后置下划线。这比缩写或错误拼写更可取。(然而,尽管有这样的规定,对于任何类的变量或参数,特别是类方法的第一个参数,‘cls’是首选的拼写方式)

           注1:参见上面对类方法的参数名的建议。

  • 对于简单的公开数据属性,最好只暴露属性名,没有复杂的访问器/修改器方法。记住,Python为将来加强提供了一条简单的途径,你应该发现简单的数据属性须要增长功能行为。在这种状况下,使用属性来隐藏简单数据属性访问语法后面的功能实现。

           注1:特性仅工做于新风格的类。
           注2:尽可能保持功能行为无反作用,尽管反作用如缓存一般是好的。
           注3:计算开销较大的操做避免使用特性,属性注解使调用者相信访问(相对)是廉价的。

  • 若是肯定你的类会被子类化,并有不想子类使用的属性,考虑用两个前导下划线无后置下划线来命名它们。这将调用Python的名称改编算法,类名将被改编为属性名。当子类不无心间包括相同的属性名时,这有助于帮助避免属性名冲突。

          注1:注意改编名称仅用于简单类名,若是一个子类使用相同的类名和属性名,仍然会有名字冲突。
          注2:名称改编会带来必定的不便,如调试和__getattr__()。然而,名称改编算法有良好的文档,也容易手工执行。
          注3:不是每一个人都喜欢名称改编。尝试平衡避免意外的名称冲突和高级调用者的可能。

 

公共和内部接口

 

任何向后兼容性保证只适用于公共接口。所以,重要的是用户可以清楚地区分公开和内部接口。

 

文档接口被认为是公开的,除非文档明确声明他们是临时或内部接口,免除一般的向后兼容保证。全部非文档化的接口应假定为内部接口。

 

为了更好的支持自省,模块应该使用__all__属性显示声明他们公开API的名字, __all__设置为一个空列表表示该模块没有公开API。
即便__all__设置的适当,内部接口(包,模块,类,函数,属性或者其它名字)仍应以一个前导下划线做前缀。

 

一个接口被认为是内部接口,若是它包含任何命名空间(包,模块,或类)被认为是内部的。

 

导入名被认为是实现细节。其它模块必须不依赖间接访问这个导入名,除非他们是一个明确的记录包含模块的API的一部分,例如os.path或包的__init__模块,从子模块暴露功能。


程序设计建议


编写的代码应该不损害其余方式的Python实现(PyPy,Jython,IronPython,Cython,Psyco等等)。

 

例如,不要依赖CPython的高效实现字符串链接的语句形式 += b或a = a + b。这种优化即便在CPython里也是脆弱的(它只适用于某些类型),而且在不使用引用计数的实现中它彻底不存在。在库的性能易受影响的部分,应使用''.join()形式。这将确保跨越不一样实现的链接发生在线性时间。

 

与单值好比None比较使用is 或is not ,不要用等号操做符。

 

一样,若是你真正的意思是if x is not None,谨防编写if x。例如,当测试一个默认是None的变量或参数是否被置成其它的值时。这个其它值多是在布尔上下文为假的类型(例如容器)。

 

使用is not 操做符而不是not...is。虽然这两个表达式的功能相同,前者更具备可读性而且更优。

article4.png

当实现有丰富的比较的排序操做时,最好实现全部六个操做符(__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语句而不是使用赋值语句将lambda表达式绑定到标识符上。

article4.png

第一种形式意味着所得的函数对象的名称是‘f’而不是通常的‘<lambda>’。这在回溯和字符串表示中更有用。赋值语句的使用消除了lambda表达式能够提供显示def声明的惟一好处(例如它能够嵌在更大的表达式里面)。

 

从Exception而不是BaseException中派生出异常。直接继承BaseException是保留那些捕捉几乎老是错的异常的。

 

设计异常层次结构基于区别,代码可能须要捕获异常,而不是捕获产生异常的位置。旨在以编程方式回答问题“出了什么问题?”,而不是只说“问题产生了”(参见PEP 3151对这节课学习内置异常层次结构的一个例子)

 

类的命名规则适用于此,只是当异常确实是错误的时候,须要在异常类名添加“Error”后缀。用于非本地的流控制或其余形式的信号的非错误的异常,不须要特殊的后缀。

 

适当使用异常链。Python3中,“raise X from Y”用来代表明确的更换而不失去原来追踪到的信息。

 

当故意替换一个内部异常(Python 2中使用“raise X”而Python 3.3+中使用“raise X from None”),确保相关的细节被转移到新的异常中(好比当转换KeyError为AttributeError时保留属性名,或在新的异常消息中嵌入原始异常的文本)。

 

Python 3中产生异常,使用raise ValueError('message')替换老的形式raise ValueError,'message'。

后一种形式是不合法的Python 3语法。

 

目前使用的形式意味着当异常的参数很长或包含格式化字符传时,多亏了小括号没必要再使用续行符。
捕获异常时,尽量说起特定的异常,而不是使用空的except:子句。
例如,使用:

article4.png

空的except:子句将捕获SystemExit和KeyboardInterrupt异常,这使得很难用Control-C来中断程序,也会掩饰其它的问题。若是想捕获会致使程序错误的全部异常,使用except Exception:(空异常至关于except BaseException:)
一条好的经验法则是限制使用空‘except’子句的两种状况:

       1.若是异常处理程序将打印或记录跟踪;至少用户将会意识到有错误发生。
       2.若是代码须要作一些清理工做,可是随后让异经常使用raise抛出。处理这种状况用try...finally更好。

当用一个名字绑定捕获异常时,更喜欢Python2.6中添加的明确的名称绑定语法。

article4.png

这是Python3中惟一支持的语法,并避免与旧的基于逗号的语法有关的歧义问题。

捕获操做系统异常时,更喜欢Python 3.3引进的明确的异常层次,经过errno值自省。

另外,对于全部的try/except子句,限制try子句到必须的绝对最少代码量。这避免掩盖错误。

article4.png

当一个资源是一个局部特定的代码段,它使用后用with语句确保迅速可靠的将它清理掉。也可使用try/finally语句。
不管什么时候作了除了获取或释放资源的一些操做,应该经过单独的函数或方法调用上下文管理器。例如:

article4.png

后者的例子没有提供任何信息代表__enter__和__exit__方法作了什么除了事务结束后关闭链接。 在这种状况下,明确是很重要的。
返回语句保持一致。函数中的全部返回语句都有返回值,或都没有返回值。若是任意一个返回语句有返回值,那么任意没有返回值的返回语句应该明确指出return None,而且明确返回语句应该放在函数结尾(若是能够)。

article4.png

使用字符串方法代替string模块。

字符串方法老是更快而且与unicode字符串使用相同的API。若是必须向后兼容Python2.0之前的版本,无视这个原则。
使用“.startswith() ”和“.endswith()”代替字符串切片来检查前缀和后缀。

startswith()和endswith()更清晰,而且减小错误率。例如:

article4.png

对象类型的比较使用isinstance()代替直接比较类型。

article4.png

当检查一个对象是不是字符串时,牢记它也多是一个unicode字符串!Python 2中,str和unicode有共同的基类basestring,因此你能够这么作:

article4.png

注意,Python3中, unicode和basestring再也不存在(只有str),而且字节对象再也不是string(而是一个integers序列)
对于序列(字符串,列表,元组),利用空序列是false的事实。

article4.png

不要书写依赖后置空格的字符串。这些后置空格在视觉上没法区分,而且有些编辑器(或最近,reindent.py)将去掉他们。
不要用==来将布尔值与True或False进行比较。

article4.png

Python标准库不使用函数注解,因为它将给一个特定的注释风格形成过早的承诺。相反,注释是留给用户去发现和试验的有用的注释样式。

 

建议第三方实验注释使用一个相关的修饰符代表解释器若是解释注解来试验注解。

 

早期的核心开发人员尝试使用显示不一致的函数注解,特别的注释风格。例如:

[str]是模糊的,它是表明一个字符串列表仍是一个能够是str或None的值。

 

符号open(file:(str,bytes))被用于值是 bytes或str替代包含一个str紧跟一个bytes值的二元元组。

 

seek(whence:int)注解展现出了一个规定外和规范内的混合:int限制太多(任何与__index__将被容许),它还不够严格(只有值0,1,和2是容许的)。一样的,write(b:bytes)注解也有太多限制(任何支持缓冲协议的将被容许)。

 

有些注解如read1(n:int=None)是自相矛盾的由于None不是一个int值。有些注解如assource_path(self,fullname:str) -> object,使人困惑它的返回类型是什么。

 

除了以上的,注解在具体类型和抽象类型的使用上是不一致的:int与Integral相对,set/frozenset与MutableSet/Set相对。
抽象基类的一些注解是不正确的规范。例如,set-to-set操做须要Other是另外一个Set的实例而不是一个Iterable。

另外一个问题是注解成为规范的一部分,但它没有被测试。

 

在大多数状况下,文档字符串已经包含了类型规范,而且比函数注解更清晰。在其他的状况下,一旦注解被移除文档字符串将改进。
所见到的函数注解太特别并且与一个自动类型检查或参数验证的连贯系统不一致。在代码中留下这些注解将使它之后更难作出改变以便自动化工具支持。

脚注

 

[5]悬挂缩进是段落中除第一行以外其它全部行都缩进的格式。在Python中,这个术语用来描述左括号括起来的语句,这行的最后非空白的字符,随后行缩进,直到右括号。

 

参考

 

[1]PEP 7,van Rossum写的C编码风格指南
[2]Barry的GNU Mailman风格指南
 http://barry.warsaw.us/software/STYLEGUIDE.txt
[3]http://www.wikipedia.com/wiki/CamelCase
[4]PEP 8现代化,2013年7月http://bugs.python.org/issue18472
版权
这个文档已经放置在公共领域。
来源:https://hg.python.org/peps/file/tip/pep-0008.txt

 

 

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

译者: wangyc

相关文章
相关标签/搜索