PEP8, Python代码书写风格指导

Introduction

This document gives coding conventions for the Python code comprising the standard library in the main Python distribution. Please see the companion informational PEP describing style guidelines for the C code in the C implementation of Python [1].

这篇文档为Python编程(包括Python主要版本中的标准库)提供编程的惯用约定. 请参考Python的C语言实现中的, 描述C语言编程风格规范的PEP[1].

This document and PEP 257 (Docstring Conventions) were adapted from Guido’s original Python Style Guide essay, with some additions from Barry’s style guide [2].

这篇文档和PEP 257(<Docstring Conventions>)是由Guido的<Python Style Guide>和Barry的编码风格规范的部分内容改编[2].

This style guide evolves over time as additional conventions are identified and past conventions are rendered obsolete by changes in the language itself.

编码风格规范随着时间会有所变化, 因为随着语言自身的更迭, 会产生新的惯用约定, 废弃旧的惯用约定.

Many projects have their own coding style guidelines. In the event of any conflicts, such project-specific guides take precedence for that project.

很多项目有他们自己的编程风格规范. 对于冲突的地方, 以项目的风格为优先.

A Foolish Consistency is the Hobgoblin of Little Minds

One of Guido’s key insights is that code is read much more often than it is written. The guidelines provided here are intended to improve the readability of code and make it consistent across the wide spectrum of Python code. As PEP 20 says, “Readability counts”.

Guido的核心观点是阅读代码远多于书写代码. 这里提供的指导目的在于提高代码的可读性和Python语言范围中代码的一致性. 如PEP 20所言, 可读性很重要.

A style guide is about consistency. Consistency with this style guide is important. Consistency within a project is more important. Consistency within one module or function is the most important.

风格指导与一致性息息相关. 书写与此指导风格一致的代码很重要. 书写与项目风格一致的代码更加重要. 在一个模块或函数内, 书写风格一致的代码超级重要.

However, know when to be inconsistent — sometimes style guide recommendations just aren’t applicable. When in doubt, use your best judgment. Look at other examples and decide what looks best. And don’t hesitate to ask!

然而, 必须要知道什么时候可以去写不一致的风格–有时候风格指导并不适用. 困惑的话就遵从你自己. 多看看别的例子, 自己决定怎么写最好看. 多问!

In particular: do not break backwards compatibility just to comply with this PEP!

尤其要注意, 不要为了保持和这篇PEP一致而破坏和过去代码风格的兼容性.

Some other good reasons to ignore a particular guideline:

这里有一些可以无视特定规范的情形:

  1. When applying the guideline would make the code less readable, even for someone who is used to reading code that follows this PEP.
  2. To be consistent with surrounding code that also breaks it (maybe for historic reasons) — although this is also an opportunity to clean up someone else’s mess (in true XP style).
  3. Because the code in question predates the introduction of the guideline and there is no other reason to be modifying that code.
  4. When the code needs to remain compatible with older versions of Python that don’t support the feature recommended by the style guide.
  1. 遵循这个PEP会让代码对于一般人, 甚至习惯于阅读此PEP规范代码的人的可读性变差这种情况.
  2. 为了与上下文代码风格一致(当上下文的风格也违背了这个PEP, 可能由于历史原因etc), 当然这也是一个规范代码风格的机会(改变上下文的风格).
  3. 早于这篇PEP的, 并且没有理由去修改的代码.
  4. 需要保持与不支持这些风格指导的Python早期版本的兼容性的代码.

Code lay-out

Indentation

Use 4 spaces per indentation level.

$每层缩进4个空格.

Continuation lines should align wrapped elements either vertically using Python’s implicit line joining inside parentheses, brackets and braces, or using a hanging indent [7]. When using a hanging indent the following should be considered; there should be no arguments on the first line and further indentation should be used to clearly distinguish itself as a continuation line.

分行应该按包裹的元素对齐, 要么按括号, 内部空间对齐, 要么悬挂缩进. 如果悬挂缩进[7]. 要考虑这些: 参数不放在首行, 后面的缩进要和悬挂缩进有明显区分.

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.
# 悬挂缩进多缩进一个层级(4空格).
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)

The 4-space rule is optional for continuation lines.

在分行情况下4空格原则是可以无视的.

Optional:

# Hanging indents *may* be indented to other than 4 spaces.
# 悬挂缩进可以不是4空格
foo = long_function_name(
  var_one, var_two,
  var_three, var_four)

When the conditional part of an if-statement is long enough to require that it be written across multiple lines, it’s worth noting that the combination of a two character keyword (i.e. if), plus a single space, plus an opening parenthesis creates a natural 4-space indent for the subsequent lines of the multiline conditional. This can produce a visual conflict with the indented suite of code nested inside the if-statement, which would also naturally be indented to 4 spaces. This PEP takes no explicit position on how (or whether) to further visually distinguish such conditional lines from the nested suite inside the if-statement. Acceptable options in this situation include, but are not limited to:

if语句长到必须分行时, 注意到if+空格+括号正好是4空格, 这可能会和if里的执行语句的缩进冲突, 这篇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()

(Also see the discussion of whether to break before or after binary operators below.)

(参见下面的关于是应该在二元操作符前还是后换行的讨论)

The closing brace/bracket/parenthesis on multiline constructs may either line up under the first non-whitespace character of the last line of list, as in:

多行间的闭括号可以和最后一行的第一个非空格字符对齐, 如下:

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

or it may be lined up under the first character of the line that starts the multiline construct, as in:

或和这个多行结构的首字符对齐, 如下:

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

Tabs or Spaces?

Spaces are the preferred indentation method.

用空格缩进是推荐的做法.

Tabs should be used solely to remain consistent with code that is already indented with tabs.

$除非你要与老代码保持一致, 否则不要用tab缩进.

Python 3 disallows mixing the use of tabs and spaces for indentation.

Python3不允许混合空格和tab来缩进.

Python 2 code indented with a mixture of tabs and spaces should be converted to using spaces exclusively.

Python2的混合缩进应该要改写成空格缩进.

When invoking the Python 2 command line interpreter with the -t option, it issues warnings about code that illegally mixes tabs and spaces. When using -tt these warnings become errors. These options are highly recommended!

调用Python2命令时候加上-t参数, 混合缩进会有警告, 加上-tt参数, 混合缩进会被报错, 这两个参数建议你使用.

Maximum Line Length

Limit all lines to a maximum of 79 characters.

$每行最多79字符.

For flowing long blocks of text with fewer structural restrictions (docstrings or comments), the line length should be limited to 72 characters.

对于那种长文本块(如文档注释和注释), 行长度应该被限制在72字符.

Limiting the required editor window width makes it possible to have several files open side-by-side, and works well when using code review tools that present the two versions in adjacent columns.

把编辑器宽度调成窄一点, 这可以并排打开多个文件, 而且能很好的使用代码检查工具(这个工具会在相邻两列比较两个版本的文件).

The default wrapping in most tools disrupts the visual structure of the code, making it more difficult to understand. The limits are chosen to avoid wrapping in editors with the window width set to 80, even if the tool places a marker glyph in the final column when wrapping lines. Some web based tools may not offer dynamic line wrapping at all.

大多数工具的默认的换行设定打破了代码的视觉效果, 让代码难以理解. 代码宽度限制就是为了避免在编辑器宽度设为80时的代码换行效果, 即便工具折叠功能会在行尾有个标志符号. 有些网页端的工具可能没有提供动态的换行设定.

Some teams strongly prefer a longer line length. For code maintained exclusively or primarily by a team that can reach agreement on this issue, it is okay to increase the nominal line length from 80 to 100 characters (effectively increasing the maximum length to 99 characters), provided that comments and docstrings are still wrapped at 72 characters.

一些团队非常推崇长的行长度. 如果代码只由或主要由他们维护和他们内部也打成一致的话, 这种做法也OK, 当然注释啥的还是要维持在72字符以内的.

The Python standard library is conservative and requires limiting lines to 79 characters (and docstrings/comments to 72).

Python标准包的写法完全遵守行长度的限制.

The preferred way of wrapping long lines is by using Python’s implied line continuation inside parentheses, brackets and braces. Long lines can be broken over multiple lines by wrapping expressions in parentheses. These should be used in preference to using a backslash for line continuation.

换行的推荐方法是遵照Python的隐式连接法–长行可以写成由括号包裹的短行. 这个方法优先于使用\换行.

Backslashes may still be appropriate at times. For example, long, multiple with-statements cannot use implicit continuation, so backslashes are acceptable:

有时候\也是被推荐的用法, 比如长的, 多的 with语句不能使用隐式行连接, 这时候使用\是可以的.

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

(See the previous discussion on multiline if-statements for further thoughts on the indentation of such multiline with-statements.)

(参见前面的关于多行的if语句的讨论, 思考多行with语句的缩进方法)

Another such case is with assert statements.

另一个类似的情况是assert语句.

Make sure to indent the continued line appropriately.

确认后续的行缩进正常.

Should a line break before or after a binary operator?

For decades the recommended style was to break after binary operators. But this can hurt readability in two ways: the operators tend to get scattered across different columns on the screen, and each operator is moved away from its operand and onto the previous line. Here, the eye has to do extra work to tell which items are added and which are subtracted:

数十年来, 建议的风格是在二元操作符后换行. 但这会损害可读性, 两个方面: 操作符分散, 操作符和操作数分离. 眼睛累.

# No: operators sit far away from their operands
income = (gross_wages +
          taxable_interest +
          (dividends - qualified_dividends) -
          ira_deduction -
          student_loan_interest)

To solve this readability problem, mathematicians and their publishers follow the opposite convention. Donald Knuth explains the traditional rule in his Computers and Typesetting series: “Although formulas within a paragraph always break after binary operations and relations, displayed formulas always break before binary operations” [3].

为了解决这个可读性问题, 数学家和出版商遵循了另一种惯用约定. Donald Knuth在<Computers and Typesetting>系列说明了这种惯用约定(懒得翻译).

Following the tradition from mathematics usually results in more readable code:

遵循数学界的传统, 于是有了更可读的代码.

# Yes: easy to match operators with operands
income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends)
          - ira_deduction
          - student_loan_interest)

In Python code, it is permissible to break before or after a binary operator, as long as the convention is consistent locally. For new code Knuth’s style is suggested.

Python对在二元操作符前或后换行没有限制, 按你方便的来, 对新的代码, 推荐Knuth的风格.

Blank Lines

Surround top-level function and class definitions with two blank lines.

顶层函数和类前后空两行.

Method definitions inside a class are surrounded by a single blank line.

类内的方法前后空一行.

Extra blank lines may be used (sparingly) to separate groups of related functions. Blank lines may be omitted between a bunch of related one-liners (e.g. a set of dummy implementations).

$可以保守的使用空行来分隔函数组. 单行的, 相互关联的函数(如匿名函数)之间不需要空行隔开.

Use blank lines in functions, sparingly, to indicate logical sections.

$在函数内部保守的用空行来分隔逻辑块.

Python accepts the control-L (i.e. ^L) form feed character as whitespace; Many tools treat these characters as page separators, so you may use them to separate pages of related sections of your file. Note, some editors and web-based code viewers may not recognize control-L as a form feed and will show another glyph in its place.

Python将control+l处理为空格; 很多工具将它当做换页符, 你可以作为文件分页标记. 注意, 有些编辑器和代码浏览器可能不支持.

Source File Encoding

Code in the core Python distribution should always use UTF-8 (or ASCII in Python 2).

文件采用UTF-8编码(或者Python2使用ASCII编码)

Files using ASCII (in Python 2) or UTF-8 (in Python 3) should not have an encoding declaration.

Python2使用ASCII, 或Python3使用UTF-8编码, 不需要有编码声明.

In the standard library, non-default encodings should be used only for test purposes or when a comment or docstring needs to mention an author name that contains non-ASCII characters; otherwise, using \x, \u, \U, or \N escapes is the preferred way to include non-ASCII data in string literals.

标准包中, 不能使用非默认编码, 除非: 测试用途, 或者注释或文档注释要提及非ASCII编码的字符. 一般而言, 使用\x,\u,\U,\N.

For Python 3.0 and beyond, the following policy is prescribed for the standard library (see PEP 3131): All identifiers in the Python standard library MUST use ASCII-only identifiers, and SHOULD use English words wherever feasible (in many cases, abbreviations and technical terms are used which aren’t English). In addition, string literals and comments must also be in ASCII. The only exceptions are (a) test cases testing the non-ASCII features, and (b) names of authors. Authors whose names are not based on the Latin alphabet (latin-1, ISO/IEC 8859-1 character set) MUST provide a transliteration of their names in this character set.

Python3或更高版本, 对于标准包有以下这些政策(见PEP 3131): 变量名必须使用ASCII字符, 和(如果可用)使用英文字符(很多情况下会有非英语的缩写和术语). 除此之外, 字符串和注释也必须是ASCII字符, 除了: (a)测试非ASCII字符, (b)作者姓名, 作者的姓名如果不是拉丁字母, 必须有在改字母集下的翻译.

Open source projects with a global audience are encouraged to adopt a similar policy.

鼓励有着全球用户的开源项目也遵循以上政策.

Imports

Imports should usually be on separate lines, e.g.:

$导入语句应该单独列一行, 如:

# Yes
import os
import sys

# No
import sys, os

It’s okay to say this though:

这样也行:

from subprocess import Popen, PIPE

Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.

$导入语句永远放置在文件顶部, 模块注释或文档注释之后, 模块全局变量和常量之前.

Imports should be grouped in the following order:

  1. standard library imports
  2. related third party imports
  3. local application/library specific imports

You should put a blank line between each group of imports.

导入应该有以下顺序:

  1. 标准包
  2. 相关的第三方包
  3. 本地应用\包,

不同组的导入用一行隔开

Absolute imports are recommended, as they are usually more readable and tend to be better behaved (or at least give better error messages) if the import system is incorrectly configured (such as when a directory inside a package ends up on sys.path):

建议绝对路径导入, 因为这样通常更加易读, 也会在导入系统被错误配置(如包里的文件路径以sys.path结尾)有更好的表现(至少可以提供更好的报错信息).

import mypkg.sibling
from mypkg import sibling
from mypkg.sibling import example

However, explicit relative imports are an acceptable alternative to absolute imports, especially when dealing with complex package layouts where using absolute imports would be unnecessarily verbose:
显性相对导入也可以接受, 尤其是当处理比较复杂的包布局, 而绝对导入太冗长.

from . import sibling
from .sibling import example

Standard library code should avoid complex package layouts and always use absolute imports.

标准包代码应该避免复杂的包布局, 保证总是使用绝对导入.

Implicit relative imports should never be used and have been removed in Python 3.

隐性的相对导入已经在Python3中被移除.

When importing a class from a class-containing module, it’s usually okay to spell this:

当从模块导入类时, 可以这样:

from myclass import MyClass
from foo.bar.yourclass import YourClass

If this spelling causes local name clashes, then spell them

如果导致了命名冲突, 则:

import myclass
import foo.bar.yourclass

and use “myclass.MyClass” and “foo.bar.yourclass.YourClass”.

Wildcard imports (from <module> import *) should be avoided, as they make it unclear which names are present in the namespace, confusing both readers and many automated tools. There is one defensible use case for a wildcard import, which is to republish an internal interface as part of a public API (for example, overwriting a pure Python implementation of an interface with the definitions from an optional accelerator module and exactly which definitions will be overwritten isn’t known in advance).

避免这样写from <module> import *, 因为他们不能明晰表示命名空间中存在什么名称, 是读者和自动化工具困惑. 有一种情形成为保留这种方式的原因: 就是发布一个内部的接口作为公共API(如重写一个纯Python实现, 需要引用到别的模块的命名, 而这些命名并不被预先知道).

When republishing names this way, the guidelines below regarding public and internal interfaces still apply.

Module level dunder names

Module level “dunders” (i.e. names with two leading and two trailing underscores) such as __all__, __author__, __version__, etc. should be placed after the module docstring but before any import statements except from __future__ imports. Python mandates that future-imports must appear in the module before any other code except docstrings.

$模块级的超级方法(开头结尾都有__的方法, 如 __all__, __author__, __version__等), 应该在模块文档注释之后, 导入语句之前(除了__future__导入). Python认定__future__导入必须出现在模块中任何其他代码之前(除了文档注释).

For example:

例如:

"""This is the example module.

This module does stuff.
"""

from __future__ import barry_as_FLUFL

__all__ = ['a', 'b', 'c']
__version__ = '0.1'
__author__ = 'Cardinal Biggles'

import os
import sys

String Quotes

In Python, single-quoted strings and double-quoted strings are the same. This PEP does not make a recommendation for this. Pick a rule and stick to it. When a string contains single or double quote characters, however, use the other one to avoid backslashes in the string. It improves readability.

'"在Python中是不区分的, 在这PEP种也不作区别, 保持自身一致就行, 如果遇到在字符串中有引号的情况, 优先避免使用\.

For triple-quoted strings, always use double quote characters to be consistent with the docstring convention in PEP 257.

$对于三引号的字符串, 总是使用双引号, 与PEP 257一致

Whitespace in Expressions and Statements

Pet Peeves

Avoid extraneous whitespace in the following situations:

避免额外的空格(以下情况下的空格是不合适的):

  • Immediately inside parentheses, brackets or braces.
  • 在开括号后直接使用空格
# 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, )
  • Immediately before a comma, semicolon, or colon:
  • 直接在逗号, 分号, 冒号之前使用空格
# Yes:
if x == 4: print x, y; x, y = y, x
# No:
if x == 4 : print x , y ; x , y = y , x
  • However, in a slice the colon acts like a binary operator, and should have equal amounts on either side (treating it as the operator with the lowest priority). In an extended slice, both colons must have the same amount of spacing applied. Exception: when a slice parameter is omitted, the space is omitted.
  • 然而有些情况, 冒号表现为二元操作符(作为最低级的), 应该左右两边有这相同的空格. 更进一步, 两个冒号也要有一样的空格, 除了: 参数缺失, 空格也不需要加上了.
# 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]
  • Immediately before the open parenthesis that starts the argument list of a function call:
  • 在函数调用的开括号前加入空格:
# Yes
spam(1)
# No:
spam (1)
  • Immediately before the open parenthesis that starts an indexing or slicing:
  • 切片或索引的开方括号前加空格:
# Yes:
dct['key'] = lst[index]
# No:
dct ['key'] = lst [index]
  • More than one space around an assignment (or other) operator to align it with another.
  • 为了对齐, 在赋值号或其他操作符前后加多个空格:
# Yes:
x = 1
y = 2
long_variable = 3
# No:
x             = 1
y             = 2
long_variable = 3

Other Recommendations

  • Avoid trailing whitespace anywhere. Because it’s usually invisible, it can be confusing: e.g. a backslash followed by a space and a newline does not count as a line continuation marker. Some editors don’t preserve it and many projects (like CPython itself) have pre-commit hooks that reject it.
  • 不要尝试给把空格挂在最后. 因为空格通常不可见, 它可能会导致歧义: 比如, 在\后跟一个空格和一个新行, \将不会被认为是多行连接符. 一些编辑器不会保存它, 很多项目有提交前检查来拒绝这种情形.
  • Always surround these binary operators with a single space on either side: assignment (=), augmented assignment (+=, -= etc.), comparisons (==, <, >, !=, <>, <=, >=, in, not in, is, is not), Booleans (and, or, not).
  • $这些符号前后总是保留一个空格: 赋值号=, 变量赋值号+=,-=等, 比较符==,<,>,!=,<>,in等, 布尔操作and,or,not.
  • If operators with different priorities are used, consider adding whitespace around the operators with the lowest priority(ies). Use your own judgment; however, never use more than one space, and always have the same amount of whitespace on both sides of a binary operator.
  • 有着不同优先级的操作符被使用, 在最低优先级的操作符左右加空格. 按你自己的标准来就行; 不要使用超过一个空格, 而且操作符左右的空格数一样.
# 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 = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)
  • Don’t use spaces around the = sign when used to indicate a keyword argument or a default parameter value.
  • $参数赋值或设定默认参数时候, =两端不设空格.
# 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)
  • Function annotations should use the normal rules for colons and always have spaces around the -> arrow if present. (See Function Annotations below for more about function annotations.)
  • 函数注释遵循冒号左右空格的处理法则, ->左右要用空格(查看下面的Function Annotations).
# Yes:
def munge(input: AnyStr): ...
def munge() -> AnyStr: ...
# No:
def munge(input:AnyStr): ...
def munge()->PosInt: ...
  • When combining an argument annotation with a default value, use spaces around the = sign (but only for those arguments that have both an annotation and a default).
  • 如果在函数注释里说明参数默认值, =号左右要有空格
# 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): ...
  • Compound statements (multiple statements on the same line) are generally discouraged.
  • 一行写多条语句是不建议的.
# 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()
  • While sometimes it’s okay to put an if/for/while with a small body on the same line, never do this for multi-clause statements. Also avoid folding such long lines!
  • 有时候if,for,while同行接一个短的语句是可以的, 但多重判断和处理为连续多行是不可取的.
# 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()

When to use trailing commas

Trailing commas are usually optional, except they are mandatory when making a tuple of one element (and in Python 2 they have semantics for the print statement). For clarity, it is recommended to surround the latter in (technically redundant) parentheses.

逗号置尾是可选项, 除非表示只有一个元素的tuple(Python2中, 逗号置尾是有语法含义的). 为了明晰, 建议为以下示例的第二条前后加上括号(冗余).

# Yes:
FILES = ('setup.cfg',)
# OK, but confusing:
FILES = 'setup.cfg',

When trailing commas are redundant, they are often helpful when a version control system is used, when a list of values, arguments or imported items is expected to be extended over time. The pattern is to put each value (etc.) on a line by itself, always adding a trailing comma, and add the close parenthesis/bracket/brace on the next line. However it does not make sense to have a trailing comma on the same line as the closing delimiter (except in the above case of singleton tuples).

闭括号处于新行的, 多个元素并列的情况下, 为了方便之后追加的写法, 建议在最后一个元素后加个逗号, 如果不是这种情况, 就不用.

# Yes:
FILES = [
    'setup.cfg',
    'tox.ini',
    ]
initialize(FILES,
           error=True,
           )

# No:
FILES = ['setup.cfg', 'tox.ini',]
initialize(FILES, error=True,)

Comments

Comments that contradict the code are worse than no comments. Always make a priority of keeping the comments up-to-date when the code changes!

与代码矛盾的注释不如没有. 代码变更后及时更新注释!

Comments should be complete sentences. The first word should be capitalized, unless it is an identifier that begins with a lower case letter (never alter the case of identifiers!).

注释是完整的句子, 首字符大写, 除非是定义的变量名(不要改变定义的变量名的大小写).

Block comments generally consist of one or more paragraphs built out of complete sentences, with each sentence ending in a period.

块注释一般有一或多个段落, 段落有一或多句, 每句以句号结尾.

You should use two spaces after a sentence-ending period in multi- sentence comments, except after the final sentence.

多句注释在每句(除了最后一句)后空两格.

When writing English, follow Strunk and White.

按照Strunk和White(的作品<The Elements of Style>)书写英文.

�Python coders from non-English speaking countries: please write your comments in English, unless you are 120% sure that the code will never be read by people who don’t speak your language.

非英语国家的Python开发者们: 请用英语来书写注释, 除非你们100%确信你们的代码不会被不懂你们语言的人阅读.

Block Comments

Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a # and a single space (unless it is indented text inside the comment).

块注释一般适用于一些(或全部)它后面的代码, 每行以#开头(除非注释内文本有缩进).

Paragraphs inside a block comment are separated by a line containing a single #.

块注释内的段落由一个#独占一行分隔.

Inline Comments

Use inline comments sparingly.

保守使用行内注释

An inline comment is a comment on the same line as a statement. Inline comments should be separated by at least two spaces from the statement. They should start with a # and a single space.

$行内注释与代码同行, 与代码间至少隔两个空格, 并以#开头.

Inline comments are unnecessary and in fact distracting if they state the obvious.

如果行内注释提供的信息在代码中显而易见, 那它就是多余的, 只能造成干扰.

# Don't do this:
x = x + 1                 # Increment x

# But sometimes, this is useful:
x = x + 1                 # Compensate for border

Documentation Strings

Conventions for writing good documentation strings (a.k.a. “docstrings”) are immortalized in PEP 257.

文档注释的惯用约定参考PEP 257

Write docstrings for all public modules, functions, classes, and methods. Docstrings are not necessary for non-public methods, but you should have a comment that describes what the method does. This comment should appear after the def line.

公开的模块, 函数, 类, 方法要有文档注释. 非公开的不必要, 但应该有个注释描述方法做什么用的. 注释应该出现在def行之后.

PEP 257 describes good docstring conventions. Note that most importantly, the “”” that ends a multiline docstring should be on a line by itself, e.g.:

PEP 257描述了文档注释的惯用约定. 结束处的"""应该自成一行.

"""Return a foobang

Optional plotz says to frobnicate the bizbaz first.
"""

For one liner docstrings, please keep the closing “”” on the same line.

单行的文档注释, 两个"""置于同一行.

Naming Conventions

The naming conventions of Python’s library are a bit of a mess, so we’ll never get this completely consistent — nevertheless, here are the currently recommended naming standards. New modules and packages (including third party frameworks) should be written to these standards, but where an existing library has a different style, internal consistency is preferred.

Python包的命名风格有点混乱, 所以做不到完全一致的风格. 现在有以下建议(新的模块和包应该遵循, 但已有的遵照自身内部一致性):

Overriding Principle

Names that are visible to the user as public parts of the API should follow conventions that reflect usage rather than implementation.

用户可见的作为API的命名遵循”命名反映用途, 而非实现”的原则.

Descriptive: Naming Styles

There are a lot of different naming styles. It helps to be able to recognize what naming style is being used, independently from what they are used for.

变量命名的风格应独立于命名的含义.

The following naming styles are commonly distinguished:

有以下几种主要的命名法.

b # (single lowercase letter) 单个小写字符

B # (single uppercase letter) 单个大写字符

lowercase # 小写单词

lower_case_with_underscores # 下划线连接的小写单词

UPPERCASE # 大写单词

UPPER_CASE_WITH_UNDERSCORES # 下划线连接的大写单词

CapitalizedWords
# (or `CapWords`, or `CamelCase` -- so named because of the bumpy look of its letters [4]). 
# This is also sometimes known as StudlyCaps.
# Note: When using acronyms in CapWords, capitalize all the letters of the acronym. Thus HTTPServerError is better than HttpServerError.
# $缩写要保证所有字符大写.

mixedCase # (differs from CapitalizedWords by initial lowercase character!)

Capitalized_Words_With_Underscores # (ugly!)

There’s also the style of using a short unique prefix to group related names together. This is not used much in Python, but it is mentioned for completeness. For example, the os.stat() function returns a tuple whose items traditionally have names like st_mode, st_size, st_mtime and so on. (This is done to emphasize the correspondence with the fields of the POSIX system call struct, which helps programmers familiar with that.)

也有使用短前缀来表示相关的变量名, Python中不常用. 如: os.stat()返回元组的原来的元素名是类似于st_mode,st_size之类的(这是为了强调它们与POSIX的调用结构的关联, 这能帮助开发者熟悉).

The X11 library uses a leading X for all its public functions. In Python, this style is generally deemed unnecessary because attribute and method names are prefixed with an object, and function names are prefixed with a module name.

X11模块为它的公共函数命名使用了X的开头, Python认为这种风格是不必要的, 因为调用属性和方法前会写明对象, 调用函数会写明函数所属的模块.

In addition, the following special forms using leading or trailing underscores are recognized (these can generally be combined with any case convention):

此外, 以_开头或结尾的命名风格也是可以的.

# weak "internal use" indicator. E.g. from M import * does not import objects whose name starts with an underscore.
# $内部使用, 当你用 from M import * 语句导入时, 以_开头的内容不会被导入.
_single_leading_underscore

# used by convention to avoid conflicts with Python keyword, e.g.
# 以_结尾的命名通常用于避免与Python关键字冲突的情形.
single_trailing_underscore_

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

# when naming a class attribute, invokes name mangling (inside class FooBar, __boo becomes _FooBar__boo; see below).
# 属性
__double_leading_underscore

# "magic" objects or attributes that live in user-controlled namespaces. E.g. __init__, __import__ or __file__. Never invent such names; only use them as documented.
__double_leading_and_trailing_underscore__

Prescriptive: Naming Conventions

Names to Avoid

Never use the characters ‘l’ (lowercase letter el), ‘O’ (uppercase letter oh), or ‘I’ (uppercase letter eye) as single character variable names.

$l,O,I不要单独用作变量名.

In some fonts, these characters are indistinguishable from the numerals one and zero. When tempted to use ‘l’, use ‘L’ instead.
有些字体下, 上述的这些字符可能会不容易被区分.

ASCII Compatibility

Identifiers used in the standard library must be ASCII compatible as described in the policy section of PEP 3131.

Package and Module Names

Modules should have short, all-lowercase names. Underscores can be used in the module name if it improves readability. Python packages should also have short, all-lowercase names, although the use of underscores is discouraged.

模块要短, 小写的命名, 包也是, 但不建议在包的命名中使用_.

When an extension module written in C or C++ has an accompanying Python module that provides a higher level (e.g. more object oriented) interface, the C/C++ module has a leading underscore (e.g. _socket).

当一个C语言或C++语言写的拓展包有一个更高抽象层级的Python包, 这个C或C++包应该以一个_开头.

Class Names

Class names should normally use the CapWords convention.

$类名遵循首字母大写风格.

The naming convention for functions may be used instead in cases where the interface is documented and used primarily as a callable.

函数的命名根据接口的文档调整.

Note that there is a separate convention for builtin names: most builtin names are single words (or two words run together), with the CapWords convention used only for exception names and builtin constants.

内建变量命名有两种惯用约定: 大多是小写的一两个单词(没有下划线连接), 一些首字母大写风格用于常量和异常.

Type variable names

Names of type variables introduced in PEP 484 should normally use CapWords preferring short names: T, AnyStr, Num. It is recommended to add suffixes _co or _contra to the variables used to declare covariant or contravariant behavior correspondingly. Examples:

PEP 484介绍了类型变量的命名, 一般推荐短小的, 首字母大写(T,AnyStr,Num). 建议使用_co,contra后缀表示可变或不可变. 例如:

from typing import TypeVar

VT_co = TypeVar('VT_co', covariant=True)
KT_contra = TypeVar('KT_contra', contravariant=True)

Exception Names

Because exceptions should be classes, the class naming convention applies here. However, you should use the suffix “Error” on your exception names (if the exception actually is an error).

Exception的命名同类的命名规范, 如果是个Error, 则以Error结尾.

Global Variable Names

(Let’s hope that these variables are meant for use inside one module only.) The conventions are about the same as those for functions.

全局变量命名同模块内方法命名规范一样.

Modules that are designed for use via from M import * should use the all mechanism to prevent exporting globals, or use the older convention of prefixing such globals with an underscore (which you might want to do to indicate these globals are “module non-public”).

用作导入全部的模块, 应使用__all__的机制来防止导入全局变量, 或者使用_前缀来命名不想被导入的变量避免它被导入(这种命名法表示你标志这些变量为非公开的模块变量).

Function and variable names

Function names should be lowercase, with words separated by underscores as necessary to improve readability.

函数命名是小写单词, 以_连接(如果多个单词能提高可读性的话).

Variable names follow the same convention as function names.

变量命名规范同函数.

mixedCase is allowed only in contexts where that’s already the prevailing style (e.g. threading.py), to retain backwards compatibility.

首字符小写的命名风格仅在为了兼容历史代码可以被接受.

Function and method arguments

Always use self for the first argument to instance methods.

实例方法的首个参数写为self.

Always use cls for the first argument to class methods.

类方法的首个参数写为cls.

If a function argument’s name clashes with a reserved keyword, it is generally better to append a single trailing underscore rather than use an abbreviation or spelling corruption. Thus class_ is better than clss. (Perhaps better is to avoid such clashes by using a synonym.)

如果函数参数名与Python关键字冲突, 建议添加_后缀, 而不是用缩写或去除元音(如class写为class_, 而不是clss, 最好还是避免冲突的情况).

Method Names and Instance Variables

Use the function naming rules: lowercase with words separated by underscores as necessary to improve readability.

方法和实例变量的命名和函数一样.

Use one leading underscore only for non-public methods and instance variables.

非公开的方法和实例变量以_开头.

To avoid name clashes with subclasses, use two leading underscores to invoke Python’s name mangling rules.

为了避免子类继承和父类的命名冲突, 使用__前缀来和Python的命名修饰规则兼容.

Python mangles these names with the class name: if class Foo has an attribute named __a, it cannot be accessed by Foo.__a. (An insistent user could still gain access by calling Foo._Foo__a.) Generally, double leading underscores should be used only to avoid name conflicts with attributes in classes designed to be subclassed.

Python将这些命名和类命名修饰在一起: 如果类Foo有一个__a属性, 它不能被通过Foo.__a访问(可以通过Foo._Foo__a访问到), 通常而言, 这种情况是用于避免子类和父类的命名冲突.

Note: there is some controversy about the use of __names (see below).

关于这有些争论, 下面会提到.

Constants

Constants are usually defined on a module level and written in all capital letters with underscores separating words. Examples include MAX_OVERFLOW and TOTAL.

$常量通常是模块级别的, 写法如: MAX_OVERFLOW,TOTAL.

Designing for inheritance

Always decide whether a class’s methods and instance variables (collectively: “attributes”) should be public or non-public. If in doubt, choose non-public; it’s easier to make it public later than to make a public attribute non-public.

Public attributes are those that you expect unrelated clients of your class to use, with your commitment to avoid backward incompatible changes. Non-public attributes are those that are not intended to be used by third parties; you make no guarantees that non-public attributes won’t change or even be removed.

We don’t use the term “private” here, since no attribute is really private in Python (without a generally unnecessary amount of work).

Another category of attributes are those that are part of the “subclass API” (often called “protected” in other languages). Some classes are designed to be inherited from, either to extend or modify aspects of the class’s behavior. When designing such a class, take care to make explicit decisions about which attributes are public, which are part of the subclass API, and which are truly only to be used by your base class.

With this in mind, here are the Pythonic guidelines:

Public attributes should have no leading underscores.

考虑好你的类的属性是公开的还是非公开的, 如果不确定, 先写成非公开的, 方便以后改, 公开属性不应该以_开头.

If your public attribute name collides with a reserved keyword, append a single trailing underscore to your attribute name. This is preferable to an abbreviation or corrupted spelling. (However, notwithstanding this rule, ‘cls’ is the preferred spelling for any variable or argument which is known to be a class, especially the first argument to a class method.)

Note 1: See the argument name recommendation above for class methods.

For simple public data attributes, it is best to expose just the attribute name, without complicated accessor/mutator methods. Keep in mind that Python provides an easy path to future enhancement, should you find that a simple data attribute needs to grow functional behavior. In that case, use properties to hide functional implementation behind simple data attribute access syntax.

Note 1: Properties only work on new-style classes.

Note 2: Try to keep the functional behavior side-effect free, although side-effects such as caching are generally fine.

以上不翻了.

Note 3: Avoid using properties for computationally expensive operations; the attribute notation makes the caller believe that access is (relatively) cheap.

$属性不应该是那种需要大量计算的内容.

If your class is intended to be subclassed, and you have attributes that you do not want subclasses to use, consider naming them with double leading underscores and no trailing underscores. This invokes Python’s name mangling algorithm, where the name of the class is mangled into the attribute name. This helps avoid attribute name collisions should subclasses inadvertently contain attributes with the same name.

如果你设计的父类会派生子类, 有些方法不想让子类继承, 可以以__开头, 不以_结尾的风格命名它们, 这会触发Python的名称修饰机制.

Note 1: Note that only the simple class name is used in the mangled name, so if a subclass chooses both the same class name and attribute name, you can still get name collisions.

Note 2: Name mangling can make certain uses, such as debugging and getattr(), less convenient. However the name mangling algorithm is well documented and easy to perform manually.

Note 3: Not everyone likes name mangling. Try to balance the need to avoid accidental name clashes with potential use by advanced callers.

Public and internal interfaces

Any backwards compatibility guarantees apply only to public interfaces. Accordingly, it is important that users be able to clearly distinguish between public and internal interfaces.

只对公开接口保证向前兼容性, 相应的, 让用户能够清楚的区分公开和内部接口.

Documented interfaces are considered public, unless the documentation explicitly declares them to be provisional or internal interfaces exempt from the usual backwards compatibility guarantees. All undocumented interfaces should be assumed to be internal.

写于文档的接口应该是被认为公开的, 除非特别声明, 所有没有列在文档上的接口应该被认为是内部的.

To better support introspection, modules should explicitly declare the names in their public API using the all attribute. Setting all to an empty list indicates that the module has no public API.

模块的所有公开接口应在__all__里声明, 如果__all__是空列表, 说明该模块没有公开接口.

Even with all set appropriately, internal interfaces (packages, modules, classes, functions, attributes or other names) should still be prefixed with a single leading underscore.

内部接口应该以_开头.

An interface is also considered internal if any containing namespace (package, module or class) is considered internal.

如果使用了内部的命名空间, 这个接口应该也是内部的.

Imported names should always be considered an implementation detail. Other modules must not rely on indirect access to such imported names unless they are an explicitly documented part of the containing module’s API, such as os.path or a package’s init module that exposes functionality from submodules.

除非是文档明确说明的公开接口, 模块不能依赖导入的名称.

Programming Recommendations

  • Code should be written in a way that does not disadvantage other implementations of Python (PyPy, Jython, IronPython, Cython, Psyco, and such).

For example, do not rely on CPython’s efficient implementation of in-place string concatenation for statements in the form a += b or a = a + b. This optimization is fragile even in CPython (it only works for some types) and isn’t present at all in implementations that don’t use refcounting. In performance sensitive parts of the library, the ”.join() form should be used instead. This will ensure that concatenation occurs in linear time across various implementations.

  • 采用一种不会因为其他的Python实现方式而产生不利的写法.
    如用CPython的这种拼接字符的高效写法a += ba = a + b, 在其他的Python实现并不一定高效. 建议使用''.join(), 它以线性时间复杂度实现字符拼接.
  • Comparisons to singletons like None should always be done with is or is not, never the equality operators.
  • $对None进行比较, 要用is, is not.

Also, beware of writing if x when you really mean if x is not None — e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!

  • 当在用if x表达if x is None时候, 一定要有清楚的认识, 就是x的类型的某些实例可能在布尔语境下为false.
  • Use is not operator rather than not … is. While both expressions are functionally identical, the former is more readable and preferred.
  • $用is not而不是not is.
# Yes:
if foo is not None:
# No:
if not foo is None:
  • When implementing ordering operations with rich comparisons, it is best to implement all six operations (__eq__,__ne__, __lt__, __le__, __gt__, __ge__) rather than relying on other code to only exercise a particular comparison.

To minimize the effort involved, the functools.total_ordering() decorator provides a tool to generate missing comparison methods.

PEP 207 indicates that reflexivity rules are assumed by Python. Thus, the interpreter may swap y > x with x < y, y >= x with x <= y, and may swap the arguments of x == y and x != y. The sort() and min() operations are guaranteed to use the < operator and the max() function uses the > operator. However, it is best to implement all six operations so that confusion doesn’t arise in other contexts.

  • $当要实现一个可比较类时候, 建议实现这六个__eq__,__ne__, __lt__, __le__, __gt__, __ge__方法.
    为了减小工作量, functools.total_ordering()装饰器可以帮忙实现.
    PEP 207说明了Python中, 自反性是默认满足的, 所以建议完全实现以上六个方法.
  • Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier.
# Yes:
def f(x): return 2*x
# No:
f = lambda x: 2*x

The first form means that the name of the resulting function object is specifically ‘f’ instead of the generic ‘<lambda>’. This is more useful for tracebacks and string representations in general. The use of the assignment statement eliminates the sole benefit a lambda expression can offer over an explicit def statement (i.e. that it can be embedded inside a larger expression)

  • def来声明函数, 而不是将匿名函数命名.
    示例中, 第一个更易错误回溯和表达.

  • Derive exceptions from Exception rather than BaseException. Direct inheritance from BaseException is reserved for exceptions where catching them is almost always the wrong thing to do.

Design exception hierarchies based on the distinctions that code catching the exceptions is likely to need, rather than the locations where the exceptions are raised. Aim to answer the question “What went wrong?” programmatically, rather than only stating that “A problem occurred” (see PEP 3151 for an example of this lesson being learned for the builtin exception hierarchy)

Class naming conventions apply here, although you should add the suffix “Error” to your exception classes if the exception is an error. Non-error exceptions that are used for non-local flow control or other forms of signaling need no special suffix.

  • $从Exception而不是BaseException继承.
  • Use exception chaining appropriately. In Python 3, “raise X from Y” should be used to indicate explicit replacement without losing the original traceback.

When deliberately replacing an inner exception (using “raise X” in Python 2 or “raise X from None” in Python 3.3+), ensure that relevant details are transferred to the new exception (such as preserving the attribute name when converting KeyError to AttributeError, or embedding the text of the original exception in the new exception message).

  • 适当的使用异常链.
  • When raising an exception in Python 2, use raise ValueError(‘message’) instead of the older form raise ValueError, ‘message’.

The latter form is not legal Python 3 syntax.

The paren-using form also means that when the exception arguments are long or include string formatting, you don’t need to use line continuation characters thanks to the containing parentheses.

  • Python 2中, 用raise ValueError('msg')而不是老的写法raise ValueError 'msg', 后一种在Python 3中是不合法的.
  • When catching exceptions, mention specific exceptions whenever possible instead of using a bare except: clause.
# For example, use:
try:
    import platform_specific_module
except ImportError:
    platform_specific_module = None

A bare except: clause will catch SystemExit and KeyboardInterrupt exceptions, making it harder to interrupt a program with Control-C, and can disguise other problems. If you want to catch all exceptions that signal program errors, use except Exception: (bare except is equivalent to except BaseException:).

A good rule of thumb is to limit use of bare ‘except’ clauses to two cases:

  1. If the exception handler will be printing out or logging the traceback; at least the user will be aware that an error has occurred.
  2. If the code needs to do some cleanup work, but then lets the exception propagate upwards with raise. try…finally can be a better way to handle this case.
  • $except:语句要指定尽量特定的异常类型, 如果想要捕获全部异常, 用except exception:.
  • When binding caught exceptions to a name, prefer the explicit name binding syntax added in Python 2.6:
try:
    process_data()
except Exception as exc:
    raise DataProcessingFailedError(str(exc))

This is the only syntax supported in Python 3, and avoids the ambiguity problems associated with the older comma-based syntax.

  • 将捕获的异常命名, 用如示例的写法.
  • When catching operating system errors, prefer the explicit exception hierarchy introduced in Python 3.3 over introspection of errno values.
  • Additionally, for all try/except clauses, limit the try clause to the absolute minimum amount of code necessary. Again, this avoids masking bugs.
  • 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)
  • When a resource is local to a particular section of code, use a with statement to ensure it is cleaned up promptly and reliably after use. A try/finally statement is also acceptable.
  • with来做上下文管理, try/finally也行
  • Context managers should be invoked through separate functions or methods whenever they do something other than acquire and release resources.
# Yes:
with conn.begin_transaction():
    do_stuff_in_transaction(conn)
# No:
with conn:
    do_stuff_in_transaction(conn)

The latter example doesn’t provide any information to indicate that the enter and exit methods are doing something other than closing the connection after a transaction. Being explicit is important in this case.

  • 上下文管理器应该被独立调用, 而不仅仅是用作获取和释放资源.
    后一个例子就没有提供任何__enter____exit__要做的事情的信息.
  • Be consistent in return statements. Either all return statements in a function should return an expression, or none of them should. If any return statement returns an expression, any return statements where no value is returned should explicitly state this as return None, and an explicit return statement should be present at the end of the function (if reachable).
# 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)
  • $函数中的return要有一致性, 若某出写了return, 那就应该在函数其他出口处明确写return None
  • Use string methods instead of the string module.

String methods are always much faster and share the same API with unicode strings. Override this rule if backward compatibility with Pythons older than 2.0 is required.

  • 使用string方法而不是string模块.
  • Use ”.startswith() and ”.endswith() instead of string slicing to check for prefixes or suffixes.

startswith() and endswith() are cleaner and less error prone. For example:

# Yes:
if foo.startswith('bar'):
# No:
if foo[:3] == 'bar':
  • $使用''.startswith()''.endswith()而不是字符串切片来检查字符串前后缀.
  • Object type comparisons should always use isinstance() instead of comparing types directly.
# Yes:
if isinstance(obj, int):
# No:
if type(obj) is type(1):

When checking if an object is a string, keep in mind that it might be a unicode string too! In Python 2, str and unicode have a common base class, basestring, so you can do:

if isinstance(obj, basestring):

Note that in Python 3, unicode and basestring no longer exist (there is only str) and a bytes object is no longer a kind of string (it is a sequence of integers instead)

  • $类型比较使用isinstance()而不是直接比较类型.
    注意Python 2中的strunicode, 它们共有父类是basestring.
    注意Python 3中, unicodebasestring不复存在, bytes也不认为是字符串的一种.
  • 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):
  • 空串的布尔值为false.
  • Don’t write string literals that rely on significant trailing whitespace. Such trailing whitespace is visually indistinguishable and some editors (or more recently, reindent.py) will trim them.
  • 不要在字符串末尾留下多个空格.
  • Don’t compare boolean values to True or False using ==.
# Yes:
if greeting:
# No:
if greeting == True:
# Worse:
if greeting is True:
  • $不要比较布尔值.

Function Annotations

With the acceptance of PEP 484, the style rules for function annotations are changing.

PEP 484被采纳后, 函数注释的风格也发生变化(参考PEP 484).

  • In order to be forward compatible, function annotations in Python 3 code should preferably use PEP 484 syntax. (There are some formatting recommendations for annotations in the previous section.)
  • The experimentation with annotation styles that was recommended previously in this PEP is no longer encouraged.
  • However, outside the stdlib, experiments within the rules of PEP 484 are now encouraged. For example, marking up a large third party library or application with PEP 484 style type annotations, reviewing how easy it was to add those annotations, and observing whether their presence increases code understandability.
  • The Python standard library should be conservative in adopting such annotations, but their use is allowed for new code and for big refactorings.
  • For code that wants to make a different use of function annotations it is recommended to put a comment of the form: # type: ignore near the top of the file; this tells type checker to ignore all annotations. (More fine-grained ways of disabling complaints from type checkers can be found in PEP 484.)
  • Like linters, type checkers are optional, separate tools. Python interpreters by default should not issue any messages due to type checking and should not alter their behavior based on annotations.
  • Users who don’t want to use type checkers are free to ignore them. However, it is expected that users of third party library packages may want to run type checkers over those packages. For this purpose PEP 484 recommends the use of stub files: .pyi files that are read by the type checker in preference of the corresponding .py files. Stub files can be distributed with a library, or separately (with the library author’s permission) through the typeshed repo [5].
  • For code that needs to be backwards compatible, type annotations can be added in the form of comments. See the relevant section of PEP 484 [6].

Variable annotations

PEP 526 introduced variable annotations. The style recommendations for them are similar to those on function annotations described above:

  • Annotations for module level variables, class and instance variables, and local variables should have a single space after the colon.
  • There should be no space before the colon.
  • If an assignment has a right hand side, then the equality sign should have exactly one space on both sides.
# Yes:
code: int

class Point:
    coords: Tuple[int, int]
    label: str = '<unknown>'
# No:
code:int  # No space after colon
code : int  # Space before colon

class Test:
    result: int=0  # No spaces around equality sign
  • Although the PEP 526 is accepted for Python 3.6, the variable annotation syntax is the preferred syntax for stub files on all versions of Python (see PEP 484 for details).
    原文作者:wuutiing
    原文地址: https://www.jianshu.com/p/c95bb22b4663
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞