在翻译PEP8中学习 — Style Guide for Python Code

翻译了好久, 终于把这篇文档翻完了, 学到很多.
自从考研结束后就没有翻译过文章了, 一开始还以为考研英语78分的我翻译能力还可以, 结果打脸. 凡是得练习啊!

官方原文:
PEP8 Style Guide for Python Code

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.
本文档给出了包含主python发行版中标准库的python代码的编码约定。请参见公司信息PEP描述的用C实现的python中的C代码中的风格指南。

This document and PEP 257 (Doc string Conventions) were adapted from Guido’s original Python Style Guide essay, with some additions from Barry’s style guide.
这篇文档和PEP 257 (约定文档) 改编自Guido最初的python代码风格指南文章, 并从Barry的风格指南总添加了一些内容.

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. (当使用这个规范会导致代码可读性下降时, 甚至对于习惯于阅读遵守这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). (为了和周围代码保持一致有时也会打破这个规则(可能是历史原因), 尽管这是一个可以用来清理别人代码混乱的机会(正真的XP风格))
  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. (当代码需要和老版本的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. 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.
续行应使用 python的隐式行连接圆括号,括号,花括号, 或者使用一个悬挂缩进对齐被包装的元素. 当使用一个悬挂时应该考虑一下内容: 这里起始行应没有参数, 应使用进一步的缩进将其作为一个续行而进行清楚地区分.

# Yes:
# Aligned with opening delimiter (分隔符).
foo = long_function_name(var_one, var_two,
                         var_three, var_four)

# Add 4 spaces (an extra level of indentation) to distinguish arguments from the rest.
def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)

# Hanging indents should add a level.
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个空格的规范对于 续行 来说也是可选的)

# Hanging indents *may* be indented to other than 4 spaces.
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 multi line 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语句中的缩进的代码集产生视觉冲突, 而这同样会自然地缩进4空格. PEP规范没有明确的立场关于如何(或者是否)进一步在视觉上区分这种条件行 与嵌套在里面的if语句. 这种情况下可接受的选项包括, 但是并不限于:

# 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.)
(参见下面关于是否在二元运算符之前或之后中断的讨论。)

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 multi line 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.
Tabs 应该只能用在已经使用制表符来缩进的代码中, 以保持一致.

Python 3 disallows mixing the use of tabs and spaces for indentation.
python 3 不允许混用tabs和空格来缩进.

Python 2 code indented with a mixture of tabs and spaces should be converted to using spaces exclusively.
python 2 代码使用tabs和空格的混合来作为缩进, 应该被转换为单独使用空格.

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!
当使用-t 选项调用python 2 命令行解释器时, 它会发出警告: 非法混合tabs和空格的代码. 当使用 -tt 这样事, 警告会变成错误. 这些选项值得强烈推荐!

Maximum Line Length

Limit all lines to a maximum of 79 characters.
对所有行来说, 最大容纳79字符.

For flowing long blocks of text with fewer structural restrictions (doc strings or comments), the line length should be limited to 72 characters.
对于结构限制较少的长文本块(doc strings或注释),行长度应限制为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的编辑器中换行, 即使当在换行时工具会在最后一列放置一个glyph标志. 一些基于工具的web, 可能根本不会提供动态换行.

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 line length limit up to 99 characters, provided that comments and doc strings are still wrapped at 72 characters.
一些团队强烈希望有一个更长的行长度. 对于专门维护或者主要由团队维护的代码, 可以对此达成统一见解. 延长行的最大长度限制至99字符是可以的, 前提是评论和doc string仍然需要限制在72字符以内.

The Python standard library is conservative and requires limiting lines to 79 characters (and doc strings/comments to 72).
python 标准库是保守的, 要求限制行数至79字符( doc string/comment 至72)

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())
# 卧槽, 还可以这样写, 涨知识了

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” .
为了解决这个可读性问题, 数学家和他们的出版商遵循了相反的惯例. Donald Knuth 在他的计算机和排版系列中解释了传统的规则: 尽管一个段落中的公式总是在二进制运算和关系之后中断, 但显示的公式总是在二进制运算之前中断.

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 表单提要字符作为空白. 一些工具把这些字符当做是页分隔符, 所以你可以使用它们来分隔文件的相关部分的页面. 注意, 一些编辑器和基于web的代码查看器可能不能识别control-L作为表单提要, 将会在该处用另一种glyph来标志.

Source File Encoding

Code in the core Python distribution should always use UTF-8 (or ASCII in Python 2).
在核心python发布版本中的代码, 应该始终使用UTF-8(在python2中使用ASCII).

Files using ASCII (in Python 2) or UTF-8 (in Python 3) should not have an encoding declaration.
在python 2中使用ASCII或者在python 3中使用UTF-8的文件, 不应该有编码声明.

In the standard library, non-default encodings should be used only for test purposes or when a comment or doc string 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.
在标准库中, 非默认的编码应该只用来测试目的或者当注释/doc string 中有涉及包含非ASCII字符的作者名时使用. 否则, 使用\x, \u或者\N 转义 是在字符串文本中来包含非ASCII数据的首选方法.

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.
对于python 3.0 以及更高版本, 标准库规定了以下策略(看PEP 3131) : 在python 官方库中所有的标识符必须使用仅ASCII标识符, 并且在可行的情况下使用英文单词(在一些案例中, 缩写和技术词条不是英文的). 除此以外, 字符串文本和注释必须使用ASCII. 唯一的例外是测试非ASCII特性和作者名的测试用例. 名称不基于拉丁字母(拉丁-1,ISO/IEC 8859-1字符集)的作者必须在此字符集中提供其名称的音译

Open source projects with a global audience are encouraged to adopt a similar policy.
鼓励那些拥有全球受众的开源项目来采用类似的策略.

Imports

Imports should usually be on separate lines:

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 总是放在文件的顶部, 在模块注释和doc string 的后面, 在模块的全局变量和常量的前面.

Imports should be grouped in the following order:
imports 应该以下面顺序来分组:

  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.
你应该将在每个导入的组之间添加空行.

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.
隐式相对导入应该从不使用, 而且已经被python 3 移除了.

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 explicitly:
如果这个拼写会导致本地名字冲突, 则显式拼写.

import myclass
import foo.bar.yourclass

# and use "myclass.MyClass" and "foo.bar.yourclass.YourClass".

Wild card imports (from <module> import *) should be avoided, as they make it unclear which names are present in the name space, confusing both readers and many automated tools. There is one defensible use case for a wild card 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 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 doc string but before any import statements except from __future__ imports. Python mandates that future-imports must appear in the module before any other code except doc strings:
模块级”dunders”( 即 名字带有两个前导和两个尾随下划线的名称), 例如__ all __ ,__ author __ , __ version __ 等, 应放在doc string 模块后面, 但是除了 from __ future __ imports 之外的任何导入语句的前面. python要求将来的导入必须出现在模块中除了doc strings 之外的任何代码之前.

"""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 doc string convention in PEP 257.
对于三引号字符串, 始终使用双引号字符以符合PEP 257中的doc string约定.

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 C Python itself) have pre-commit hooks that reject it.
避免在任何地方尾随空白. 因为它通常是不可见的, 所以可能会让人困惑: 例如, 反斜杠后面跟着空白, 换行符不算作行继续标记. 有些编辑器不保存它, 许多项目(例如C python本身) 都有预提交钩子来拒绝它.

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,not in,is,is not),布尔值(and,or,not)

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

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.)
函数注释应该使用冒号的常规规则, 并且如果存在的话, 在->箭头周围总是有空格. (有关函数注释的详细信息,请参见下面的函数注释。)

# Yes
def munge(input: AnyStr): ...
def munge() -> AnyStr: ...
  
# No
def munge(input:AnyStr): ...
def munge()->PosInt: ...

Don’t use spaces around the = sign when used to indicate a keyword argument, or when used to indicate a default value for an unannotated function parameter.
当用于指示关键字参数, 或用于指示未标记函数参数的默认值时, 不要在= 号周围使用空格.

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

When combining an argument annotation with a default value, however, do use spaces around the = sign:
当将参数批注与默认值组合时, 请在= 符号周围使用空格:

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

# No:
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.
尾随逗号通常是可选的, 除非他们在构成一个元素的元组时是强制的(在python 2 中, 它们具有print语句的语义). 为了清楚起见, 建议将后者括在(技术上的冗余)括号中.

# 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.
当你写英语的时候,跟着斯特伦克和怀特.

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 程序员: 请用英文写评论, 除非你有120%的把握确信这些代码以后绝不会被那些不会自己语言的人读到.

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. “doc strings”) are immortalized in PEP 257.
编写好文档字符串的约定(也称为”doc string”) 在PEP 257 中永久化.

Write doc strings for all public modules, functions, classes, and methods. Doc strings 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.
为了所有公共模块,函数,类和方法编写doc string. Doc string 不一定是为了非公共方法, 但是应该用一个注释来描述该方法的作用是什么. 这个注释应该出现在def行的后面.

PEP 257 describes good doc string conventions. Note that most importantly, the """ that ends a multi line doc string should be on a line by itself:
PEP 257 描述了好的doc string 公约. 注意到最重要的是, 结束多行doc string 的””” 本身应该在一行上:

"""Return a foobang

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

For one liner doc strings, 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). 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_mtime, st_size等命名. (这是用来强调和POSIX系统调用结构字段对应关系, 它可以帮助编程人员熟悉它)

In addition, the following special forms using leading or trailing underscores are recognized (these can generally be combined with any case convention):
此外, 还可以识别以下使用了前导或尾随下划线的特殊表单(这些一般能够和任意约定案例结合):

  • _single_leading_underscore: weak “internal use” indicator. E.g. from M import * does not import objects whose names start with an underscore.
    _single_leading_underscore: 弱”内部使用”指标. 例如, 从 from M import * 不导入那些以下划线开头的对象.

  • single_trailing_underscore_: used by convention to avoid conflicts with Python keyword, e.g.
    single_trailing_underscore_: 约定用来避免和python关键字冲突:

    Tkinter.Toplevel(master, class_='ClassName')   # class_
    
  • __double_leading_underscore: when naming a class attribute, invokes name mangling (inside class FooBar, __boo becomes _FooBar__boo; see below).
    __ double_leading_underscore: 当命名一个类属性时, 调用 名称管理.

  • __double_leading_and_trailing_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.
    双/前导/尾随/下划线: 存在于用户控制的命名空间中的”magic” 对象或者属性.

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” (小写字母l) , “O”(大写字母O), 或者”I” (大写字母) 作为单个字符变量名.

In some fonts, these characters are indistinguishable from the numerals one and zero. When tempted to use ‘l’, use ‘L’ instead.
在一些字体中, 这些字符和其他数字和0分不清. 当试图使用”l” 时, 请使用”L”.

ASCII Compatibility

Identifiers used in the standard library must be ASCII compatible as described in the policy section of PEP 3131
标识符在标准库中使用必须是与ASCII码兼容的, 入PEP 的策略部分所述.

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.
模块应该是简短的, 都是小写的名称. 如果下划线可以提高可读性, 可以在模块名称中使用下划线. 尽管不鼓励使用下划线, python包应该也有简短的,都是小写的命名.

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:
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).
由于异常应该是类, 所以类的命名约定也同样适合这里. 然而, 你应该在你的异常名称中使用”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”).
为了使用 from M import * 而设计的模块, 应该使用 __ 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.
混合的例子 只有在那些已经流行的样式中的上下文中才能被允许(比如threading.py) , 为的是保留向后的兼容性.

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.)
如果一个函数的参数名和一个保留的关键字冲突了, 通常更好的做法是附加一个单独的尾随下划线, 而不是用一个缩写或者拼写错误. 因此, 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).
注意: 关于 __names 的用法有一些争议(如下):

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 and 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.
始终决定一个类方法和实例变量(统称为: “attributes”) 是否应该是公共的还是非公共的. 如果有疑问, 选择非公共的; 相比较将公共属性设置为非公共的, 稍后将其变成公共的更容易.

Public attributes are those that you expect unrelated clients of your class to use, with your commitment to avoid backwards 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.
公共属性是那些你希望类中使用的不相关的clients的属性, 并且你承诺避免向后不兼容的变更. 非公共的属性是那些不打算由第三方使用的属性. 你不能保证非公共属性将不会更改或者甚至被移除.

We don’t use the term “private” here, since no attribute is really private in Python (without a generally unnecessary amount of work).
我们这里不使用”private”词条, 因为在python中没有正真私有的属性( 没有通常不必要地工作量).

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.
另一类别属性是属于”子类API” ( 在其他语言中经常被称作”protected”). 一些类设计成继承自 类行为的扩展或者修改的层面. 当设计这样的类时, 要注意明确地决定: 哪些属性时公共的, 哪些是subclass API的部分, 哪些只是被基类使用的.

With this in mind, here are the Pythonic guidelines:
考虑到这一点, 下面是pythonic 指南:

  • 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.)
    如果你的公共属性名和一个保留的关键字冲突了, 在你的属性名后添加一个尾随下划线. 这比缩写或者拼写错误更可取. ( 但是, 尽管有这条规则的, 对于已知为类的任何变量或者参数, 尤其是作为一个类方法的第一个参数, “cls” 是首选拼写. )
    Note 1: See the argument name recommendation above for class methods.
    注意1: 对于类方法参看上面的参数命名建议.

  • 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.
    对于简单的公共的数据属性, 最好只公开属性名, 而不使用复杂的访问器/装换器方法. 如果你发现一个简单的数据属性需要增长函数行为, 那么python对未来的加强提供了一个简单的途径, . 在那种情况下, 可以使用属性来隐藏 在简单数据属性访问语法背后的函数的实现.

    Note 1: Properties only work on new-style classes.
    注意1: 属性仅适用于新式类.

    Note 2: Try to keep the functional behavior side-effect free, although side-effects such as caching are generally fine.
    注意2: 尽量保持函数行为的副作用是免费的, 尽管缓存这样的副作用一般是较好的.

    Note 3: Avoid using properties for computationally expensive operations; the attribute notation makes the caller believe that access is (relatively) cheap.
    注意3: 避免在计算代价高昂的操作中使用属性; 属性表示法使得调用者相信访问(相对) 低廉.

  • 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.
    注意1: 注意只有简单的类名可以在名称管理中被使用, 所以如果一个子类选择既有相同的类名,又有属性名, 那么你可以仍然会导致冲突.

    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.
    注意2: 命名管理可以使得某些用途不是很方便, 例如调试和 __getattr__(). 然而, 命名管理算法可以有很好的文档记录并且容易手动实现.

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__属性在其公共API中显式声明名称. 设置 __all__ 为一个空列表预示着模块没有公共的API.

Even with __all__ set appropriately, internal interfaces (packages, modules, classes, functions, attributes or other names) should still be prefixed with a single leading underscore.
即使对 __all__ 进行了适当地设置, 内部接口(包,模块, 类, 函数, 属性或者其他名称) 应该依然用一个单独的前导下划线来作为前缀.

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.
导入名称应该永远视为一个实现细节. 其他模块必须不依赖于间接地访问这些类导入的名称, 除非他们是一个包含模块的API的明确记录部分, 例如os.path 或者包的 __init__ 模块, 该模块公开子模块的功能.

Programming Recommendations

  • Code should be written in a way that does not disadvantage other implementations of Python (PyPy, Jython, IronPython, Cython, Psyco, and such).
    代码的编写方式不应影响其他Python实现.

    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.

    例如,不要依赖cpython对形式为a+=b或a=a+b的语句的就地字符串连接的有效实现。即使在cpython中,这种优化也是脆弱的(它只对于某些类型起作用),并且在不使用refcounting的情况下根本无法实现。在库的性能敏感部分中,应改用 ''.join() 形式。这将确保在不同实现之间以线性时间发生连接。

  • Comparisons to singletons like None should always be done with is or is not, never the equality operators.
    像None这样的单例比较应该始终用is或者is not, 而不是使用 equality 运算符.

    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 is not None 时应该意识 if x 的书写 . – 例如, 当你测试一个的默认值为None的变量或者参数是否被设置为其他值时. 另一个值的类型(例如一个容纳) 可能在布尔上下文中是错误的.

  • 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.
    执行具有丰富的比较来实现排序操作时, 最好执行所有的六个操作(__eq__, __ne__, __lt__, __le__, __gt__, __ge__) , 而不是依赖其他代码仅仅运算一个特殊的比较.

    To minimize the effort involved, the functools.total_ordering() decorator provides a tool to generate missing comparison methods.
    为了最小化所涉及的工作, functools.total_ordering()装饰器提供了一个工具可以用来生成所缺的比较的方法.

    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.
    PEP207表示反射性规则由python假定。因此,解释器可以用x<y交换y>x,用x<=y交换y>=x,可以用x=y和x交换参数 x!=y . Sort()和Min()操作保证使用<运算符,Max()函数使用>运算符。但是,最好实现这六个操作,这样在其他上下文中就不会出现混淆。

  • Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier.
    始终使用一个def 语句, 而不是将lambda表达式直接 到标识符的赋值语句.

    # 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 ‘’. 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)
    第一个表单意思是结果函数对象的名称是一个特定的f 而不是一般的lambda. 这对于一般的回溯和字符串表示更有用. 使用赋值语句消除了lambda表达式相对于显式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.
    从Exception而不是BaseException派生异常.直接从BaseException继承是为异常保留的, 在异常中捕获它们几乎总是错误的.

    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)
    设计异常层次结构基于可能需要的代码捕获异常的差异, 而不是异常抛出的位置. 为了从编程角度回答”哪里出了问题”, 而不是仅仅陈述”一个问题发生了”(参看PEP 3151 中的一个示例, 关于从内置异常层次中学习到的课程)

    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.
    类命名约定也适合这里, 尽管当异常是一个错误的时候, 你应该在你的异常类后面添加”Error”的后缀. 用作非本地流控制或者其他形式的信令的非错误异常 不需要特殊后缀.

  • Use exception chaining appropriately. In Python 3, “raise X from Y” should be used to indicate explicit replacement without losing the original traceback.
    恰当地使用异常链接. 在python3 中, “从Y中抛出X异常” 应该用来指示显式替换, 而不会丢失原始的回溯.

    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).
    当故意替换一个内部异常(在Python2 中使用”raise X” 或者在Python3.3+ 中使用”raise X from None”), 确保相关的细节被传输到新的异常(例如将关键字转换为属性错误时保留属性名, 或者在新异常信息中嵌入原始异常文本)

  • When raising an exception in Python 2, use raise ValueError('message') instead of the older form raise ValueError, 'message'.
    在python2中抛出异常, 请使用raise ValueError('message'), 而不是老的形式raise ValueError, 'message'.

    The latter form is not legal Python 3 syntax.
    后一种形式不是合法的python3语法.

    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.
    当异常参数很长或者包含字符串格式的时候, paren-using意味着由于包含括号, 不需要使用续行字符.

  • When catching exceptions, mention specific exceptions whenever possible instead of using a bare except:clause:
    当捕获异常时, 尽可能提及特定的异常, 无论何时不要使用一个裸露的异常: 字句.

    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:).
    裸露的异常: 字句将会捕获SystemExit和 KeyboardInterrupt异常, 使得很难使用Ctrl+C来中断程序, 而且会掩盖其他问题. 如果想要捕获所有表示程序错误的异常, 请使用except Exception:( 裸露的异常等同于 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.
      如果代码需要做一些清理工作, 那么让异常随着raise.try...finally传播可能是处理该案例的一个更好方法.
  • When binding caught exceptions to a name, prefer the explicit name binding syntax added in Python 2.6:
    当将捕获的异常和一个名词绑定一起时, 首选python2.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.
    这是在Python3中仅支持的语法, 避免了 与旧的基于逗号语法的语法相关联的模糊性问题.

  • When catching operating system errors, prefer the explicit exception hierarchy introduced in Python 3.3 over introspection of errno values.
    当捕获操作系统错误时, 优先选择Python3.3 中引入的显式异常层次结构, 而不是对errno值进行自省.

  • 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字句限制为所需的绝对最小代码量. 而且, 这会避免隐藏的bugs.

    # 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__ and __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).
    在返回语句中保持一致. 要么函数中的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)
    
  • 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 backwards compatibility with Pythons older than 2.0 is required.
    字符串方法始终更快一些,而且与unicode字符串共享相同的API. 如果需要向后兼容性大于2.0的Python, 则重写该规则.

  • Use ''.startswith() and ''.endswith() instead of string slicing to check for prefixes or suffixes.
    使用''.startswith() and ''.endswith() 取代字符串切片可以检查前缀和后缀.

    startswith() and endswith() are cleaner and less error prone:
    startswith() and endswith() 更加干净也更不容易出错.

    Yes: if foo.startswith('bar'):
    No:  if foo[:3] == 'bar':
    
  • Object type comparisons should always use isinstance() instead of comparing types directly.
    对象类型的比较应该始终使用 isinstance(), 而不是直接比较类型.

    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:
    当检查一个对象是否是字符串时, 记住它可能是一个unicode的字符串! 在Python2中, str和unicode 有相同的基类,基础字符串, 所以你可以这样做:

    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).
    注意在Python3中, unicode 和 basestring 不再存在(仅有str) 以及一个bytes 对象不再是一种string类型( 它是一个整数序列).

  • For sequences, (strings, lists, tuples), use the fact that empty sequences are false.
    例如, (strings, lists, tuples) , 使用空序列为假的事实.

    Yes: if not seq:
         if seq:
    
    No:  if len(seq):
         if not len(seq):
    
  • 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.
    不要依赖 大量的 尾随空格来写字符串文本. 这样的尾随空格在视觉上是不可区分的, 而且一些编辑器(或者最近的reindent.py)会对其进行修剪.

  • Don’t compare boolean values to True or False using ==.
    不要使用 == 将布尔值与True或False来比较.

    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 的接受, 对于函数注释的样式规则正在改变.

  • 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.)
    为了向前的兼容性, Python3中的函数注释应该首选使用PEP 484 语法. (在前面部分中, 对于注释有一些格式上的建议).

  • The experimentation with annotation styles that was recommended previously in this PEP is no longer encouraged.
    在这个PEP中以前被推荐使用的注释样式实验, 已经不再被鼓励了.

  • 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.
    然而, 除了标准库之外, 现在正鼓励在PEP 484之内实验. 例如, 用PEP484 样式类型的注释标记大的三方库或者应用程序, 评审增加这些注释的容易程度, 观察他们的存在是否是增加代码的可理解度.

  • The Python standard library should be conservative in adopting such annotations, but their use is allowed for new code and for big refactorings.
    Python标准库应该对于采用这样的注释是保守地, 但是对于新的代码和为了大的重构来说是被允许的.

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

    在文件顶部的附近; 这告诉种类检查器来忽略所有的注释. (在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.
    像线头一样, 类型检查器是可选的, 独立的工具. 默认的Python编译器不应该任何由于类型检查而声明消息, 也不应该基于注释更改它们的行为.

  • 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.

    不想使用类型检查器的用户可以随意忽略它们. 但是, 第三方库包的用户可能想要在这些包中运行类检查器. 为了这个目的, PEP484 建议使用存根文件: .pyi文件, 这些文件是由类型检查器读取, 而不是相应的.py文件. 存根文件可以与库一起分发, 或者通过排版报告单独分发(经过作者许可).

  • 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.
    对于需要向后兼容的代码, 类型注释可以以评论的形式添加.

Variable Annotations

PEP 526 introduced variable annotations. The style recommendations for them are similar to those on function annotations described above:
PEP 526 引入了变量注释. 它们的样式建议与以上对函数注释的描述有相似之处:

  • 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).
    尽管在Python3.6中接受了 PEP 526 , 但是对于所有版本的Python来说, 变量注释是Python上根存文件的首选语法.

footnotes:

Hanging indentation is a type-setting style where all the lines in a paragraph are indented except the first line. In the context of Python, the term is used to describe a style where the opening parenthesis of a parenthesized statement is the last non-whitespace character of the line, with subsequent lines being indented until the closing parenthesis.
悬挂缩进是一种类型设置样式,除第一行外,段落中的所有行都缩进。在python上下文中,该术语用于描述一种样式,其中带括号语句的左括号是行的最后一个非空白字符,随后的行缩进到右括号。