PEP8 - Python 代码风格指南中英对照

Introduction

引言

This document gives coding conventions for Python code comprising the standard library in the main Python distribution. Please see the companion informational PEP describing style guidelines for the C code and the C implementation of Python.
本文档给出了主流的 Python 发行版(包含标准库)的编码规范。关于 Python 的 C 语言实现的代码风格指南可参阅配套的 PEP 文档。

This document and PEP257(Docstring Conventions) were adapted from Guido’s original Python style Guide essay, with some additions from Barry’s style guide.
本文档和 PEP257(文档字符串规范)改编自 Guido 的原始 Python 风格指南文章,并添加了一些 Barry 的风格指南中的内容。

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 spetrum of Python code. As PEP20 says, “Readability counts”.
Guido 的一个关键观点是:代码的阅读时间比编写时间多得多。本指南的目的在于改善代码的可读性并使其与广泛的 Python 代码保持一致。正如 PEP20 中所说:可读性非常重要。

A style guide is about consistency. Consistency with this style guide is important. Consistancy 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 dont’ 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 guidline wound 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 remian 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 haning intent. 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 elimiter.
# 与左分隔符对齐
foo = long_function_name(var_one, var_two,
                         var_thres, var_four)
# More indentation included to distinguish this from the nest.
# 以更多的缩进来区别于其它
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.
# 悬挂缩进可以不按照 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 nothing 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 confilict 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_sonething()

# 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 forbnicate.
    # 由于两个条件为真,我们可以代入
    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 multi-line 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_taskes_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

使用 Tab 还是空格

Spaces are the preferred indentation method.
空格是首选的缩进方式。

Tabs should be used solely to remain consistent with code that is already indented with tabs.
制表符应当单独使用以保持与已经使用制表符进行缩进的代码保持一致。

Python 3 disallows mixing the use of tabs and spaces for indentation.
Python 3 禁止混用制表符和空格进行缩进。

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!
当使用 -t 选项调用 python2 命令行解释器时,它会对非法混合制表符和空格的代码发出警告。当使用 -tt 时,这些警告变成错误。强烈推荐这些选项!

Maximum Line Length

行最大长度

Limit all lines to a maximum of 79 cahracters.
限制所有行至多 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 的编辑器中进行换行,即使在换行时工具在最后一列中放置了标记符号。一些基于 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 nominal line length from 80 to 100 characters (effectively increasing the maximum length to 99 charaters), provided that commends and docstring are still wrapped at 72 characters.
有些团队强烈喜欢更长的行长度。代码的专门或主要维护团队如果能够在该问题上达成协议,可以将标称行长度从 80 个字符增加到 100 个字符(有效地将最大长度增加到 99 个字符),前提是注释和文档字符串仍然限制到 72 个字符。

The Python standard library is conservative and requires limiting lines to 79 characters (and docstrings/comments to 72).
Python 标准库比较保守,要求将每行限制为 79 个字符(文档字符串/注释限制为 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 using 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-statement for further thoughts on the indentation of such multiline with-statements)
(请参阅前面关于多行 if-statements 的讨论,了解对这种多行 with-statements 缩进的进一步思考。)

Another such cases 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 operators is moved away from its operand and onto the previous line. Here, the eys has to do extra work to tell which items are added and which are substracted.
数十年来,推荐的风格都是在二元操作符之后截断。但这会在两个方面损害代码的可读性:操作符趋向于分散在屏幕的不同列中,并且各个操作符都移动到了操作数的前一行。这里,需要我们耗费额外的精力来分辨哪个元素是被加而哪个元素是被减:

# 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:
为了解决这个可读性问题,数学家和他们的出版商遵循了相反的惯例。Donald Knuth 在他的计算机和排版系列中解释了传统规则:

Although formulas within a paragraph always break after binary operations and relations, displayed formulas always break before binary operations.
虽然段落中的公式总是二元运算符和关系符之后截断,但显示的公式总是在二元运算之前截断。

Following the tradition from mathematics usually results in more readable code:
遵循数学的传统风格通常会使得代码更具可读性:

# Yes: easy to match opertors 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.
顶层函数或者类定义前后各用两个空行分隔。

Extra blank lines may be used (sparingly) to separate groups of related functions. Blank lines may be omitted between a bunch of relate one-liners (e.g. a set of dummy implementations)
额外的空行可以用来(少量的)分隔一组相关的函数。在一堆相关的单行程序(如一组虚拟的实现)之间的空行可以忽略。

Use blank lines in functions, sparingly, to indicate logical sections.
在函数中用少量的空行来指明不同的逻辑区域。

Python accepts the control-L from feeed character as whitespace; Many tools treat these characters as page separators, so you my 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 接受 ctrl-L 换页字符作为空页;一些工作把这些字符作为分页符,所以你可以用它们来分隔文件中相关部分的页面。注意,一些编辑器和基于 web 的代码查看器可能无法将 ctrl-L 识别为一个换页符,而在其位置上显示其它符号。

Source File Encoding

源文件编码

Code in the core Python distribution should always use UTF-8 (or ASCII in Python 2)
核心 Python 发行版中的代码应该始终使用 UTF-8(或 Python 2 中的 ASCII)

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

In the standard library, non-default encodings should be used only for test purposes or when a comment or dicstring needs to mention an author name that contains non-ASCII character; otherwise, using \x, \u, \U, or \N excapes is the preferred way to include non-ASCII data in string iterals.
在标准库中,非默认编码应该只用于测试目的,或者当注释或文档字符串需要提到包含非 ascii 字符的作者名称时;否则,使用 \x、\u、\u或 \N 转义是在字符串字面量中包含非 ascii 数据的首选方法。

For Python 3.0 and beyond, the following policy is prescribed for the standard libray(see PEP3131): All identifiers in the Python standard libray 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 naes are not based on the latin alphabet MUST providee a latin transliteration of their names.
对于Python 3.0及以后版本,标准库规定了以下策略(参见PEP3131):Python 标准库中的所有标识符都必须仅使用 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.:
导入包通常应当使用单独行:

正确

import os
import sys

错误:

import os, sys

不过这样也可以:

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.
每组包导入之间应当有一个空行

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 unnessarily 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-containning 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.youclass.YourClass.
并以myclass.Myclassfoo.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 defensile use case for a wildcard import, which is to republish an internal interface with the definitions fro 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

(dunder: Double UNDERscore)

Module level “dunders” (i.e. names with two leading and two trainling 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.
模块级“dunders”(即带有两个前导下划线和两个尾置下划线的名称)如__all__, __author__, __version__等应当放置在模块文档字符串之后、除了from __future__的包导入部分之前。Python 要求 future-imports 必须出现在模块中除文档字符串之外的任何其他代码之前。

例如:

"""This is the example module.

This module does stuff.
"""
from __future__ import barry_as_FLUFL

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

import os
import sys

String Quotes

字符串引号

In Python, single-quoted strings and double-quoted strings are the same. This PEP does not ake a recommendation for this. Pick a rule ans 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 consitent 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:
直接在括号、中括号或大括号内:

正确:

spam(ham[1], {eggs: 2})

错误:

spam( ham[ 1 ], { eggs: 2 } )

Between a trailing comma and a following close parenthesis:
尾置逗号和右括号之间:

正确:

foo = (0,)

错误:

bar = (0, )

正确:

if x == 4: print x, y: x, y = y, x

错误:

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.
然而,在切片中,冒号的作用就像一个二元操作符,并且应该在任意一边都有相同的数量(将其视为具有最低优先级的操作符)。在扩展切片中,两个冒号必须应用相同的间距。例外:当一个切片参数被省略时,空格被省略。

正确:

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]

错误:

ham[lower + offset:upper + offset]
ham[1: 9], ham[1 : 9], ham[1:9 :3]
ham[lower : : upper]
ham[ : upper]

Immediately before the open parethesis that starts the argument list of a function call:
在左括号之前立即开始函数调用的参数列表:

正确:

spam(1)

错误:

spam (1)

在左括号之前立即开始索引或切片:

正确

dct['key'] = lst[index]

错误:

dct ['key'] = lst [index]

More than one space around an assignment (or other) operator to align it with another.
在赋值操作符(或其他操作符)周围有一个以上的空格,使其与另一个对齐。

正确:

x = 1
y = 2
long_variable = 3

错误:

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 sollowed by a space and a newline does not count as a line continuation marker. Some editor don’t preserve it and many projects (like CPython itself) have precommit hooks that reject it.
在任何地方都要避免尾置空格,因为这是不可见的,会使人因此而困惑。例如:反斜线后跟一个空格和新行时不被记为行延续标记。一些编辑器不会保留它,且一些工程(如 Cpython 本身)利用 precommit-hooks 来拒绝该用法。

Always surround these operators with a single space on either side: assignment (=), argumented assignment (+=, -= etc), comparious (==, <, >, !=, <>, <=, >=, in, not in, is, is not), Booleans (and, or, not).
如下操作符前后应总是有一个空格:赋值(=), 增量赋值(+=, -=等), 比较(==, <, >, !=, <>, <=, >=, in, not in, is, is not),布尔(and, or, not).

If operators with different priorities are used, consider adding whitespace around the operators with lowest priority(ies). Use your own judgement; however, never use more than one space, and always have the same amount of whitespace on both sides of a binary operator.
如果使用了不同优先级的运算符,可考虑在低优先级的操作符前后加上空格。使用你自己的判断;但是,永远不要使用超过一个空格,且总在二元操作符前后使用相同数量的空格。

正确:

i = i + 1
submitted += 1
x = x*2 + 1
hypot = x*x + y*y
c = (a+b) * (a-b)

错误:

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.
当用于指示关键字参数或默认参数值时,不要在 = 号周围使用空格。

正确:

def complex(real, imag=0.0):
    return magic(r=real, i=img)

错误:

def complex(real, imag=0.0):
    return magic(r = real, i = img)

Function annotations should use the normal rules for colons and always have spaces around th -> arrow if present. (See Function Annotations below for more about function annotations)
函数注释应该使用冒号的常规规则,并且在 -> 箭头周围总是有空格(如果有的话)。(关于函数注释的更多信息,请参见下面的函数注释。)

正确:

def munge(input: AnyStr): ...
def munge() -> AnyStr: ...

错误:

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 auguments that have both an annotation and a default.)
当将参数注释与默认值组合在一起时,在 = 号周围使用空格(但仅限于那些同时具有注释和默认值的参数)。

正确:

def munge(sep: AnyStr = None): ...
def munge(input: AnyStr, sep: AnyStr = None, limit=1000): ...

错误:

def munge(input: AnyStr=None): ...
def munge(input: AnyStr, limit = 1000): ...

Compound statements (multiple statementson the same line) are generally discouraged.
通常不鼓励使用复合语句(在同一行上有多个语句)。

正确:

if foo == 'blah':
    do_blah_thing()
do_one()
do_two()
do_three()

错误:

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 和一个小主体放在同一行,但是不要在多子句语句中这样做。也不要折这么长的行!

最好不要:

if foo == 'blah': do_blah_thing()
for x in lst: total += x
while t < 10: t = delay()

坚决不要:

if foo = 'blah': do_blah_thing()
else: do_non_blah_thing()

try: something()
finally: cleanup()

do_one(); do_two(); do_three(long, argument,
                             lst, 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 statements). For clarity, it is recommended to surround the latter in (technically redundant) parentheses.
尾置逗号通常是可选的,除非在创建一个元素的元组时它们是强制性的(在 Python2 中,它们有 print 语句的语义)。为了清晰起见,建议将后者用(技术上多余的)圆括号括起来。

正确:

FILES = ('setup.cfg',)

可以,但是比较难以理解:

FILES = 'setup.cfg',

When traling commas are redundant, they are often helpful when a version control syste 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 aoma, and add the close parenthesis/bracket/brace on the next line. However it does not ake sense to have a trailing comma on the same line as the closing delimiter (except in the above case of singleton tuples).
如果尾置逗号是多余的,那么当使用版本控制系统时,当一个值、参数或导入项的列表希望随时间扩展时,它们通常是有用的。该模式是将每个值(等等)单独放在一行中,总是添加一个尾置逗号,并在下一行添加右括号/方括号/大括号。但是,在同一行中使用结尾逗号作为结束分隔符是没有意义的(除了上面的单例元组)。

正确:

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

错误:

FILES = ['setup.cfg', 'tox.ini']
initialize(FILES, erro=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. If a comment is a phrase or sentence, its first word should be capitalized, unless it is an identifier that begins with a lower case letter (never alter the case of identifiers!).
注释应当是一个完整的句子。如果一个注释是一个短语或者语句,它的首单词应当大写,除非该单词是一个小写字母开头的标识符(永远不要改变标识符的大小写)。

If a comment is short, the period at the end can be omitted. Block comments generally consist of one or more paragraphs built out of complete sentenses, and each sentence should end in a period.
如果一个注释较短,则其末尾的句号可以省略。块注释通常由一个或多个由完整的句子组成的段落组成,每个句子都应该以句号结束。

You should use two spaces after a sentence-ending period.
你应该在一个句子结束后用两个空格。

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 then, 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

内联注释

Using inline comments sparingly.
尽量少使用内联注释。

An inline comment is a comment on the same line as a statement. Inline comments should be separateed 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.
行内注释是不必要的,事实上,如果它们陈述了明显的问题,就会分散注意力。

不要这样做:

x = x + 1           # Increment x

但有时这样是有用的:

x = x + 1           # Compensate for border

Documentation strings

文档字符串

Conventions for writing good ducumentation strings (a.k.a “docstrings”) are immortalized in PEP257.
PEP257 中编写优秀的文档字符串(也称为“docstrings”)的约定永不过时。

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 comments should appear after the def line.
为所有公共模块、函数、类和方法编写文档字符串。文档字符串对于非公共方法不是必需的,但是您应该有一个注释来描述该方法的功能。这个注释应该出现在 def 行之后。

PEP257 describes good docstring conventions. Note that most impotantly, the """ that ends a multiline docstring should be on a line by itself, e.g.:
PEP257 中描述了优秀的文档字符串约定。最重要的是,结束多行文档字符串的"""应该单独在一行上,例如:

"""Return a foobang

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

For one linear 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, CamelCase, StudlyCaps)
  • mixedCase(differs from CapitalizedWords by initial lowercase character!)
  • Capitalized_Words_With_Underscores(Ugly!)

Note: When using abbreviations in CapWords, capitalize all the letters of the abbreviation. Thus HTTPServerError is better than HttpServerError.
注意:在 CapWords 中使用缩写时,将缩写的所有字母大写。因此,HTTPServerErrorHTTPServerError更好。

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 return 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、st_mtime 等。(这样做是为了强调与 POSIX 系统调用结构的字段的对应关系,这有助于程序员熟悉 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):
此外,可以识别以下使用首下划线或尾下划线的特殊形式(它们通常可以与任何大小写约定组合):

  • _single_leading_underscore:weak “internal use” indicator. E.g. from M import * does not import objects whose name starts with an underscore.
  • single_traling_underscore_:used by convention to avoid conflicts with Python keyword,e.g.:(按约定使用,以避免与Python关键字发生冲突,例如:)
    • Tkinter.Toplevel(master, class_=‘ClassName’)
  • __double_leading_underscore:when naming a class attribute, invokes name mangling (inside class FooBar, __boo becomes _FooBar__boo; see below). 当命名类属性时,调用 name mangling(在类 FooBar 中,__boo 变成_FooBar__boo;见下文)
  • __double_leading_and_trailing_underscore__:“magic” objects or attributes that live in user-controlled namespaces.E.g.__init__,__import__,__file__. Never invent such names; only use them as documented. 存在于用户控制的名称空间中的“魔法”对象或属性。例如:__init____import____file__。永远不要捏造这样的名字,只在文档中使用它们。

prescriptive: Naming Conventions

规范性:命名规范

Names to Avoid

避免使用的命名

Never use the character ‘l’ (lower case letter el), ‘O’ (uppercase letter oh), or ‘I’ (uppercase letter eye) as single character variable names.
不要使用字母’l’(小写字母el), ‘O’(大写字母oh),或’I’(大写字母eye)作为单字符变量名。

In some fonts, these characters are indistinguishable from the numerals one and zero. When tempted to use ‘l’, use ‘L’ instead.
在某些字体中,这些字符与数字 1 和 0 无法区分。当你想用 “l” 的时候,就用 “L” 代替。

ASCII Compatibility

ASCII 兼容性

Identifiers used in the standard library must be ASCII compatible as described in the policy section of PEP3131.
标准库中使用的标识符必须与 ASCII 兼容,如 PEP3131 的 policy 部分所述。

Package and Module Names

包和模块命名

Modules should have short, all-lowecase 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 包也应当使用简短的,全小写的名称,尽管不推荐使用下划线。

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++模块前导有下划线(例如_socket)。

Class Names

类命名

Class names should normally use the CapWords convention.
类名应当使用 CapWords 约定。(驼峰命名法)

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.
注意,对于内置名称有一个单独的约定:大多数内置名称是单个单词(或两个单词组合在一起),而 CapWords 约定仅用于异常名称和内置常量。

Type variable names

类型变量命名

Names of type variables introduced in PEP484 normally use CapWords preferring short names: T, AnyStr, Num. It is recommended to add suffixes _co or _contra to the varialbes used to declare convariant or congravariant behavior correspondingly. Examples
PEP484 中描述的类型的名称通常应该使用 CapWords,而不是短名称: TAnyStrNum。建议在用于声明协变或逆变行为的变量上添加后缀_co_contra。例子如下:

from typing import TypeVar
  VT_co = TypeVar('VT_co', covariant=True)
  KT_contra = TypeVar('KY_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 and underscore (which you might want to do to indicate these globals are “module non-public”).
被设计通过from M import *来使用的模块应该使用__all__机制来防止导出全局变量,或者使用以前的约定,在这些全局变量前面加下划线(你可能想这样做,以表明这些全局变量是“模块非公共的”)。

Function Names

函数命名

Function names should be lowercase, with words separated by underscores as necessary to improve readability.
函数名应该小写,单词之间用下划线分隔,以提高可读性。

mixedCase is allowed only in contexts where that’s already the prvailing style (e.g. threading.py), to retain backwards compatibility.
mixedCase 只允许在已经是主流风格的上下文中使用(例如 threading.py),以保持向后兼容性。

Function and method arguments

函数和方法参数

Always use self for the first argument to instance methods.
总是使用 self 作为实例方法的第一个参数

Always use cls for hte 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 abbreviation or spelling corruption. Thus class_ is better than clss. (Perhaps better is to avoid such clashes by using a synonym.)
如果函数参数的名称与保留关键字冲突,通常最好在后面附加一个下划线,而不是使用缩写或拼写错误。因此,class_ 比 class_ 好。(也许最好是使用同义词来避免这种冲突。)

Method Names and Instance Variables

方法命名和实例变量

Use the function nameing rules: lowercase with words separated by underscores 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 subclass.
Python 用类名来修改这些名称:如果类 Foo 有一个名为__a的属性,它不能被Foo.__a访问(足够坚持的用户仍然可以通过调用Foo._Foo__a获得访问权限。)。通常,双前导下划线应该只用于避免与设计为子类的类中的属性的名称冲突。

Note: There is some controversy about the use of __names (see below).
注意:对于 __name 的使用存在一些争议(见下文)。

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

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 paties; 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).
这里我们不使用术语“私有”,因为在 Python 中没有真正私有的属性(减少了不必要的工作量)。

Another category of attributes are those that are part of the “subclass API” (often called “protected” in other languages). Some classes are disigned to be inherited from, either to extend or modify aspects of the class’s bahavior. 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”(在其他语言中通常称为“受保护的”)的一部分。有些类被设计为被继承,扩展或修改类行为的某些方面。在设计这样的类时,要注意明确哪些属性是公共的,哪些是子类 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 perferable to an abbreviation or corrupted spelling. (However, not withstanding 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’是任何已知是类的变量或参数的首选拼写,特别是类方法的第一个参数。)
  • Note1: 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 your find that a simple data attribute needs to grow functional behavior. In that case, use properties to hide functional implementation behind simple data attribute acess syntax. 对于简单的公共数据属性,最好只公开属性名,而不公开复杂的访问/修改方法。请记住,如果发现一个简单的数据属性需要扩展函数行为,Python提供了一条易于实现未来增强的路径。在这种情况下,使用properties将函数实现隐藏在简单的数据属性访问语法后面。
  • Note1: Properties only work on new-style classes. properties 只在新式类中起作用。
  • Note2: Try to keep the functional behavior side-effect free, although side-effects such as caching are generally fine. 尽量避免函数行为的副作用,尽管缓存之类的副作用通常都没问题。
  • Note2: 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 的名称篡改算法,其中类的名称被篡改为属性名。如果子类无意中包含具有相同名称的属性,这有助于避免属性名称冲突。
  • Note1: 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. 需要注意的是只有简单的类名被用来修饰命名,所以如果子类同时选择了相同的类名和属性名,您仍然会遇到命名冲突。
  • Note2: 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. Name mangling 会使得调试、__getattr__()等的使用没那么方便。但 name mangling 算法有很好的文档并且易于手动实现。
  • Note3: Not everyone likes name mangling. Try to balance the need to avoid accidental name clashes with potential use by advanced callers. 不是每个人都喜欢 name mangling。尽量在避免命名冲突和高级调用者可能使用的需求之间取得平衡。

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 的其他实现(PyPy,Jython,IronPython,Cython,Psyco等)造成不利影响的方式编写。

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 += ba = a + b的语句原地字符串连接的高效实现。这种优化即使在 CPython 中也很脆弱(它只对某些类型有效),而且在不使用 refcounting 的实现中根本无效。在库中对性能敏感的部分,应该使用''.join()的形式。这将确保不同的 python 实现对字符串连接的效率为线性。

Comparisons to singletons like None should ahways be done with is or is not, never the equality operators.
与单例对象(如 None)的比较应该始终使用isis 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 defauts 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!
另外,当你真正的意思是如果 x 不是 None 时,要注意写if x。例如,当测试一个默认为 None 的变量或参数是否被设置为其他值时。其他值的类型(比如容器)在布尔上下文中可能是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。虽然这两个表达式在功能上是相同的,但前者可读性更好,更受欢迎。

正确:

if foo is not None:

错误:

if not foo is None:

When implementing ordering operations with rich comparisons, it is best to implement all six operation (__eq__, __ne__, __lt__, __le__, __gt__, __ge__) rather than relying on other code to only exercise a particular comparison.
在实现具有丰富比较的排序操作时,最好实现所有6个操作(__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()提供了一个用来生成缺失的比较方法的工具。

PEP207 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 auguments 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 假设存在自反性规则。因此,解释器可能交换y > xx < y,交换y >= xx <= y,且交换x == yx != 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 表达式直接绑定给一个标识符。

正确:

def f(x): return 2*x

错误:

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 assignent 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’ 而不是通用的’’。一般来说,这对于 tracebacks 和字符串表示更有用。赋值语句的使用消除了 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 thatn the locations where the exceptions are raised. Aim to answer the questioin “What went wrong?” programmatically, rather than only stating that “A problem occurred” (see PEP3151 for an example of this lesson being learned for the builtin exception hierarchy)
根据捕获异常的代码可能需要的区别来设计异常层次结构,而不是根据引发异常的位置。旨在回答“哪里出了问题?”,而不是仅仅声明“发生了一个问题”(有关内建异常层次结构,请参阅 PEP3151 中关于本问题的一个示例)。

Class naming convention 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 exceptioin chaining appropriately. In Python 3, “raise X from Y” should be used to indicate explicit replacement without losing the original trackback.
适当使用异常链接。在Python 3中,应该使用" raise X from Y "来表示进行显式替换,而不会丢失原始的回溯信息。

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 fome None),确保相关信息转移到新异常(如保护属性名称转换 KeyError AttributeError 时,或嵌入的文本原始异常在新的异常消息)。

When raising an exception in Python 2, use raise ValueError('message') instead of the older form raise ValueError, 'message'.
当在 python2 中抛出一个异常时,使用raise ValueError('message')而不是旧版格式的raise Value Error, '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 ot use the line continuation charaters thanks to the containing parentheses.
使用父类的形式还意味着,当异常参数很长或包含字符串格式时,由于包含圆括号,您不需要使用行延续字符。

When catching exceptions, mention specific exceptions whenever possible instead of using a bare except: clause.
在捕获异常时,尽可能提到特定的异常,而不是使用 except: 子句。

For example, use:
例如,使用:

try: 
    import platform_specific_module
except ImportError:
    platform_specific_module = None

A bare except: clause will catch SysntemExit 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 erros, use except Exception: (bare except is eauivalent to except BaseException😃.
一个裸的 except: 子句将捕获 SystemExit 和 KeyboardInterrupt 异常,使得用 Control-C 中断程序变得更加困难,并且会掩盖其他问题。如果您想捕获所有表明程序错误的异常,可以使用except Exception: (bare except 等价于 except BaseException:)。

A good rule of thumb is to lmit use of bare ‘except’ clause to two cases:
一条经验法则是,将 “except” 子句的使用限制在以下两种情况:

  1. If the exception handler will be printing out or logging the traceback; at least the user will be awaer that an error has occured.(如果异常处理程序将打印或记录回溯;至少用户会知道发生了错误。)
  2. If the code needs to do some cleanup work, but then lets the exception propagete upwards with raise. try...finally can be a better way to handle this case. (如果代码需要做一些清理工作,但随后让异常通过raise向上传播raise. try...finally可以更好的处理这个情况。)

When binding caught exceptions to a nae, prefer the explicit name binding syntax added in Python2.6:
当绑定异常捕获到一个名称时,请使用 Python2.6 中添加的显式名称绑定语法:

try:
    process_data()
except Exception as exc:
    raise DataProcessingFailedError(str(exc))

This is the only syntax support in Python3, 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 Python3.3 over introspection of error values.
当捕捉操作系统错误时,最好使用 Python3.3 中引入的显式异常层次结构,而不是 errno 值的内省。

Additioinally, for all try/except clause, limit the try clause to the absolute minimum amount of code necessary. Again, this avoids masking bugs.
此外,对于所有 try/except 子句,将 try 子句限制在所需的绝对最小代码量内。同样,这避免了掩蔽漏洞。

正确:

try:
    value = collection[key]
except KeyError:
    return key_not_found(key)
else:
    return handle_value(value)

错误:

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 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 funcitons or methods whenever they do something other than acquire and release resources. For example:
上下文管理器应该通过单独的函数或方法来调用,无论它们做什么,而不是获取和释放资源。例如:

正确:

with conn.begin_transaction():
    do_stuff_in_transaction(conn)

错误:

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 if the funciton (if reachable).
在 return 语句中保持一致。要么函数中的所有返回语句都应该返回一个表达式,要么都不返回。如果任何 return 语句返回一个表达式,任何没有返回值的 return 语句都应该显式地将 this 声明为 return None,并且在函数的末尾应该显示一个显式的 return 语句(如果可到达的话)。

正确:

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)

错误:

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 方法代替 string 模块。

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.
字符串方法总是更快,并且与 unicode 字符串共享相同的 API。如果需要与 2.0 以上的 python 向后兼容,请重写此规则。

Use ''.startwith() and ''.endswith() instead of string slicing to check for prefixes or suffixes.
使用''.startswith()''.endswith()代替字符串切片来检查前缀或后缀。

startwith() and endswith() are cleaner and less error prone. For example:
startswith()endswith()更简洁,更少出错。例如:
正确:

if foo.startswith('bar')

错误:

if foo[:3] == 'bar':

Object type comparisons should always use isinstance() instead of comparing types direcly:
对象类型比较应当总是使用isinstance()而不是直接比较类型。

正确:

if isinstance(obj, int):

错误:

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 有一个通用的基类 basestring,所以你可以这样做:

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),字节串对象也不再是一种字符串(而是一个整数序列)

For sequences, (strings, lists, tuples), use the fact that empty sequence are false:
对于序列(字符串,列表,元组),使用空序列为假的事实:

正确:

if not seq:
if seq:

错误:

if len(seq):
if not len(seq):

Don’t write string literals that rely on significant trailing whtespace. 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:

正确:

if greeting:

错误:

if greeting == True:

离谱:

if greeting is True:

Funtion Annotations

函数注释

With the acceptance of PEP484, the style rules for functioin annotations are changing.
随着 PEP484 被接受,函数注释的样式规则发生了变化。

  • In order to be forward compatible, funciton annotations in Python 3 code should preferably use PEP484 syntax. (There are some formatting recommendations for annotations in the previous section.) (为了向上兼容,python3 代码中的函数注释最好使用 PEP484 语法。(在上一节中有一些关于注释格式的建议。))
  • The experimentation with annotaton styles that was recommended previously in this PEP is no longer encouraged. (不再鼓励本 PEP 以前推荐的注释样式。)
  • However, outside the stdlib, experiments within the rules of PEP484 are now encouraged. For example, marking up a large third party libray or application with PEP484 style type annotations, reviewing how easy it was to add thos annotations, and observing whether their presence increase code understandability. (但是,在 stdlib 之外,现在鼓励在 PEP484 规则内进行实验。例如,用 PEP484 风格的类型注释标记大型第三方库或应用程序,检查添加这些注释有多容易,并观察它们的存在是否提高了代码的可理解性。)
  • The Python standard library shoule be conservative in adoping 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 PEP484.) (添加在文件顶部附近;这告诉类型检查器忽略所有注释。(在 PEP484 中可以找到从类型检查器禁用投诉的更细粒度的方法。))

  • 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.(像 linters 一样,类型检查器是可选的,单独的工具。默认情况下,python 解释器不应该因为类型检查而发出任何消息,也不应该基于注释改变它们的行为。)

  • Uses 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 PEP484 recommends the use of stub files: .pyi files that are read by the type chcker 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 建议使用 stub 文件: .pyi 文件,类型检查器优先读取相应的 .py 文件。.Stub 文件可以与库一起分发,也可以通过 typeshed repo 单独分发(得到库作者的许可)。)

  • For code that needs to be backwards compatible, type annotations can be added in the form of comments. See the relevant section of PEP484. (对于需要向后兼容的代码,可以以注释的形式添加类型注释。请参阅 PEP484 的相关章节)

英文原文地址:https://pep8.org

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
PEP 8是Python代码样式指南,它提供了一些规范和建议,以帮助开发者编写更具可读性和一致性的Python代码。根据PEP 8,以下是一些常见的规范和建议: 1. 文件编码:在Python文件的开头添加文件编码声明,通常使用UTF-8编码。 2. 导入顺序:按照先导入Python包,再导入第三方包,最后导入自定义的包的顺序进行导入。这样可以更清晰地组织导入语句。 3. 避免使用import *:尽量避免使用import *来导入所有模块,因为这样会导致命名空间污染和代码可读性降低。 4. 返回值:确保每个return语句都能有返回值,不能返回的应显式地返回None。这样可以提高代码的可读性和可维护性。 以上是PEP 8中的一些规范和建议,遵循这些规范可以使你的Python代码更加规范和易于理解。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [Python-Python编码规范(PEP8)](https://blog.csdn.net/lady_killer9/article/details/109150536)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v4^insert_chatgpt"}} ] [.reference_item] - *2* [python编码规范pep8](https://blog.csdn.net/m0_46673598/article/details/126274989)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v4^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值