PEP8
-
用空格,而非tab
-
一行最多79字符
-
缩进:每层缩进四个空格
-
换行:大括号、中括号、小括号,但是如果是with或assert,用“\”换行。换行效果:
a = [1,2,3 4,5,6 ]
或者:
a = [1,2,3 4,5,6 ]
-
如果需要换行的语句包含二元运算符:
income = (gross_wages + taxable_interest + (dividends - qualified_dividends) - ira_deduction - student_loan_interest)
-
空行
类与函数之间使用两个空行
类内部函数之间一个空行
Python接受control-L(即^ L)换页符作为空格; 许多工具将这些字符视为页面分隔符,因此您可以使用它们来分隔文件相关部分的页面。 请注意,某些编辑器和基于Web的代码查看器可能不会将control-L识别为换页,而将在其位置显示另一个标志符号。
-
源代码编码(source file encoding)
核心Python发行版中的代码应始终使用UTF-8
Python标准库中的所有标识符(identifier)都必须使用纯ASCII标识符,并且在可行的情况下应使用英文单词(在许多情况下,使用的缩写和技术术语不是英文)。 此外,字符串文字和注释也必须使用ASCII。 唯一的例外是(a)测试非ASCII功能的测试用例,以及(b)作者的姓名。 名称不基于拉丁字母的作者必须提供其姓名的拉丁音译。
-
import
-
一行不要导入两个包
Yes:
import os import sys
No:
import os, sys
It’s okay to say this though:
from subprocess import Popen, PIPE
-
导入应当放在Docstring之后,文件的最前面
-
导入顺序:<标准模块 - 第三方库 - 自建模块> 每个模块之间有一个空行。
-
推荐绝对导入,但是,显式相对导入(explicit relative imports)是绝对导入的一种可接受的替代方法,特别是在处理复杂的包装布局时,使用绝对导入会变得不必要地冗长, 拒绝隐式相对导入(implicit relative imports):
from . import sibling from .sibling import example
-
导入一个含类模块中的类时:
from myclass import MyClass from foo.bar.yourclass import YourClass
当这样的拼写会导致本地命名冲突时 :
import myclassimport foo.bar.yourclass
- 应该避免使用通配符导入(from import *),因为通配符使名称空间中不清楚存在哪些名称,这会混淆读取器和许多自动化工具。 通配符导入有一个合理的用例,它是将内部接口重新发布为公共API的一部分(例如,使用可选加速器模块中的定义覆盖接口的纯Python实现,以及确切的定义将是 事先未知)。
-
-
模块级别的常量的导入
对于模块级常量(前后都有双下划线)应放在文档字符串之后,但应放在除__ future __导入之外的任何导入语句之前。 Python要求future导入必须在模块中出现在除文档字符串以外的任何其他代码之前。
"""This is the example module.
This module does stuff."""
from __future__ import barry_as_FLUFL
__all__ = ['a','b','c']
__version__ = '0.1'
__autor__ = 'Cardinal Biggles'
import os
import sys
-
字符串引号
在Python中,单引号字符串和双引号字符串是相同的。 本PEP对此不做任何建议。 选择一条规则并坚持下去。 但是,当字符串包含单引号或双引号字符时,请使用另一个以避免在字符串中使用反斜杠。 它提高了可读性。
对于三引号字符串,请始终使用双引号字符以与PEP 257中的docstring约定一致。
-
空格
避免如下情况的空格,且逗号后要有空格,逗号前面不要有
-
Yes:
spam(ham[1], {eggs: 2})
No:
spam( ham[ 1 ], { eggs: 2 } )
-
Between a trailing comma and a following close parenthesis:
Yes:
foo = (0,)
No:
bar = (0, )
列表里面的冒号属于二元运算符,前后空格数量应该对称。
反斜杠后面如果加空格,将不算做换行。
当用于表示关键字参数或默认参数值时,请不要在=号前后使用空格。
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)
-
-
函数注释的空格
函数注释应使用冒号的常规规则,并且如果存在,则在->箭头周围始终留有空格。
Yes:
def munge(input: AnyStr): ...def munge() -> AnyStr: ...
No:
def munge(input:AnyStr): ...def munge()->PosInt: ...
当将参数注释与默认值组合时,请在=符号周围使用空格(但仅适用于同时具有注释和默认值的参数)。
Yes:
def munge(sep: AnyStr = None): ...def munge(input: AnyStr, sep: AnyStr = None, limit=1000): ...
No:
def munge(input: AnyStr=None): ...def munge(input: AnyStr, limit = 1000): ...
-
不要将多行代码合并,不要写单行的if语句
-
注释(comment)
与代码矛盾的注释比没有注释更糟糕。 当代码更改时,始终要始终使注释保持最新状态!
注释应为完整的句子。 如果注释是短语或句子,则除非注释是以小写字母开头的标识符,否则其第一个单词应大写(切勿更改标识符的大小写!)。
如果注释很短,则可以省略最后的句点。 整体注释通常由一个或多个完整句子组成的段落组成,每个句子都应以句点结尾。
句子结尾后应使用两个空格。
请用英文写注释
-
块注释(block comments)
块注释通常适用于其后的一些(或全部)代码,并且缩进到与该代码相同的级别。 块注释的每一行都以#和一个空格开头(除非注释中的文本是缩进的)。
块注释中的段落由包含单个#的行分隔。
-
行内注释(inline comments)
谨慎使用行内注释。
行内注释是与语句在同一行上的注释。 行内注释应与该语句至少分隔两个空格。 它们应以#和单个空格开头。
行内注释是不必要的,并且如果它们表明显而易见,则实际上会分散注意力。
-
文档字符串(documentation strings)
为所有公共模块,函数,类和方法编写文档字符串。 对于非公共方法,文档字符串不是必需的,但是您应该有一条注释,描述该方法的作用。 该注释应出现在def行之后。
PEP 257描述了良好的文档字符串约定。 请注意,最重要的是,以多行文档字符串结尾的“”应单独位于一行上,例如:"""Return a foobangOptional plotz says to frobnicate the bizbaz first."""
单行文档字符串三引号在同一行。
-
命名
缩写词的所有字母都大写
不要用i或I或O或o做变量名,因为有些字体显示不出区别。
模块应用小写名称
-
类型变量名称
在PEP 484中引入的类型变量的名称通常应使用CapWord,而应使用短名称:T,AnyStr,Num。 建议将后缀_co或_contra添加到用于分别声明协变或逆变行为的变量中。 -
尽量用def而不是lambda
-
Use
''.startswith()
and''.endswith()
instead of string slicing to check for prefixes or suffixes.startswith()
andendswith()
are cleaner and less error prone. For example:Yes:
if foo.startswith('bar'):
No:
if foo[:3] == 'bar':
-
Object type comparisons should always use
isinstance()
instead of comparing types directly:Yes:
if isinstance(obj, int):
No:
if type(obj) is type(1):
-
For sequences, (strings, lists, tuples), use the fact that empty sequences are false:
Yes:
if not seq:if seq:
No:
if len(seq):if not len(seq):
-
Don’t compare boolean values to True or False using
==
:Yes:
if greeting:
No:
if greeting == True:
Worse:
if greeting is True:
-
异常
从Exception而不是BaseException派生异常。
根据可能需要捕获异常的代码(而不是引发异常的位置)的区别来设计异常层次结构。 旨在回答“出了什么问题?”的问题 以编程方式,而不是仅仅说明“发生了问题”(请参阅PEP 3151,以了解针对内置异常层次结构学习此课程的示例)
类命名约定在此处适用,但是如果异常是错误,则应在异常类中添加后缀“ Error”。 用于非本地流控制或其他形式的信令的非错误异常不需要特殊的后缀。
适当使用异常链接。 在Python 3中,应使用“raise X from Y”来表示显式替换,而不会丢失原始回溯。
捕获异常时,请尽可能提及特定的异常,而不要使用裸露的except:子句。
For example, use:
try: import platform_specific_module except ImportError: platform_specific_module = None
仅使用except:子句将捕获SystemExit和KeyboardInterrupt异常,这使得使用Control-C中断程序更加困难,并且可以掩盖其他问题。 如果要捕获所有表示程序错误的异常,请不要使用Exception:(裸除等效于BaseException)。
一条好的经验法则是将裸’except’子句的使用限制为两种情况:
- 如果异常处理程序将打印输出或记录回溯(traceback); 至少用户会意识到发生了错误。
- 如果代码需要做一些清理工作,但随后让异常通过raise向上传播。 try finally可能是处理这种情况的更好方法。
在将捕获的异常绑定到名称时,最好使用Python 2.6中添加的显式名称绑定语法:
try: process_data() except Exception as exc: raise DataProcessingFailedError(str(exc))
这是Python 3中唯一支持的语法,并且避免了与较早的基于逗号的语法相关的歧义问题。
捕获操作系统错误时,最好使用Python 3.3中引入的显式异常层次结构,而不是对errno值的自省。
此外,对于所有try / except子句,请将try子句限制为所需的绝对最小数量的代码。 同样,这避免了掩盖错误。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)
-
当资源位于特定代码段的本地时,请使用with语句以确保在使用后立即可靠地对其进行清理。 try / finally语句也是可以接受的。
-
在返回语句中保持一致。 函数中的所有return语句应该返回一个表达式,或者都不返回。 如果任何return语句返回一个表达式,则不返回任何值的任何return语句都应将其显式声明为return None,并且在函数末尾(如果可以访问)应存在一个显式return语句。
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)
-
使用字符串方法而非字符串模块。