逸之

V1

2022/01/08阅读:74主题:红绯

PEP8

PEP 8 — the Style Guide for Python Code

PEP 8ー Python 代码样式指南

This stylized presentation of the well-established PEP 8 was created by Kenneth Reitz (for humans).

这个完善的 PEP 8的程式化表示是由 Kenneth Reitz (为人类)创建的。

Introduction 引言

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

本文档提供了构成主 Python 发行版中的标准库的 Python 代码的编码约定。请参阅相关的信息性 PEP,它描述了 Python 1的 c 实现中 c 代码的样式指南。

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

这个文档和 PEP 257(Docstring Conventions)是从 Guido 的原始 Python 样式指南文章中改编的,还有一些从 Barry 的样式指南2中添加的内容。

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

这种风格指南随着时间的推移不断发展,随着更多的约定被确定,过去的约定因语言本身的变化而变得过时。

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

许多项目都有自己的编码风格指南。在发生任何冲突时,此类特定于项目的指南将优先用于该项目。

A Foolish Consistency is the Hobgoblin of Little Minds

愚蠢的一致性是心胸狭窄者的怪癖

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

Guido 的一个关键见解是,代码被阅读的频率远远高于被编写的频率。这里提供的准则旨在提高代码的可读性,并使其在各种各样的 Python 代码中保持一致。正如 PEP 20所说,“可读性很重要”。

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

风格指南是关于一致性的。这种风格指南的一致性是很重要的。项目中的一致性更为重要。一个模块或函数的一致性是最重要的。

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

然而,要知道什么时候不一致ーー有时候时尚指南的建议就是不适用。当你犹豫不决时,运用你最好的判断力。看看其他的例子,决定什么看起来最好。不要犹豫,直接问吧!

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

特别是: 不要为了遵守这个 PEP 而破坏向后兼容性!

Some other good reasons to ignore a particular guideline:

忽略某一特定指导方针的其他一些好理由:

  1. When applying the guideline would make the code less readable, even for someone who is used to reading code that follows this PEP.
  2. 在应用准则时,代码的可读性会降低,即使对于习惯于阅读本 PEP 之后的代码的人来说也是如此。
  3. 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).
  4. 为了与周围的代码保持一致,这些代码也会破坏它(可能是出于历史原因)——尽管这也是一个机会,可以清理其他人的混乱(用真正的 XP 风格)。
  5. Because the code in question predates the introduction of the guideline and there is no other reason to be modifying that code.
  6. 因为所讨论的代码早于准则的引入,而且没有其他原因需要修改该代码。
  7. When the code needs to remain compatible with older versions of Python that don’t support the feature recommended by the style guide.
  8. 当代码需要与不支持样式指南所推荐的特性的旧版本的 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 3. 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 的隐式行连接在括号、括号和大括号内,或者使用悬挂缩进3对已包装的元素进行垂直对齐。当使用悬挂缩进时,应该考虑以下内容; 第一行上不应该有参数,应该使用进一步缩进作为连续行来清楚地区分它本身。

Yes:

是的:

# Aligned with opening delimiter.
foo = long_function_name(var_one, var_two,
                         var_three, var_four)

# More indentation included to distinguish this from the rest.
def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)

# Hanging indents should add a level.
foo = long_function_name(
    var_one, var_two,
    var_three, var_four)

No:

答案是:

# Arguments on first line forbidden when not using vertical alignment.
foo = long_function_name(var_one, var_two,
    var_three, var_four)

# Further indentation required as indentation is not distinguishable.
def long_function_name(
    var_one, var_two, var_three,
    var_four):
    print(var_one)

The 4-space rule is optional for continuation lines.

对于连续线,4空格规则是可选的。

Optional:

可选:

# Hanging indents *may* be indented to other than 4 spaces.
foo = long_function_name(
  var_one, var_two,
  var_three, var_four)

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

如果 if 语句的条件部分足够长,需要跨多行写入,那么值得注意的是,两个字符关键字(即 if)加上一个空格,再加上一个开始括号,将为多行条件的后续行创建一个自然的4空格缩进。这可能会与嵌套在 if 语句中的缩进代码套件产生视觉冲突,该套件自然也会缩进为4个空格。对于如何(或是否)从 if 语句中的嵌套套件中进一步可视地区分这些条件行,这个 PEP 没有明确的立场。在这种情况下,可接受的选择包括但不限于:

# No extra indentation.
if (this_is_one_thing and
    that_is_another_thing):
    do_something()

# Add a comment, which will provide some distinction in editors
# supporting syntax highlighting.
if (this_is_one_thing and
    that_is_another_thing):
    # Since both conditions are true, we can frobnicate.
    do_something()

# Add some extra indentation on the conditional continuation line.
if (this_is_one_thing
        and that_is_another_thing):
    do_something()

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

(另请参阅下面关于是在二进制运算符之前还是之后中断的讨论。)

The closing brace/bracket/parenthesis on 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_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.

选项卡只能用来保持代码与选项卡缩进的一致性。

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.

使用制表符和空格混合缩进的 Python 2代码应该转换为只使用空格。

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

Maximum Line Length 最大行长

Limit all lines to a maximum of 79 characters.

将所有行限制为最多79个字符。

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

对于结构限制较少的长文本块(docstring 或注释) ,行长应该限制为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 characters), provided that comments and docstrings 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个字符(docstring/comments 限制为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-statement 不能使用隐式延续,因此反斜杠是可以接受的:

with open('/path/to/some/file/you/want/to/read') as file_1, \
     open('/path/to/some/file/being/written', 'w') as file_2:
    file_2.write(file_1.read())

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

(请参阅前面关于 multiline if-statements 的讨论,以了解关于这种 multiline with-statements 缩进的进一步思考。)

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:

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

“Although formulas within a paragraph always break after binary operations and relations, displayed formulas always break before binary operations” 4.

”尽管段落中的公式总是在二进制操作和关系之后中断,但显示的公式总是在二进制操作之前中断”4。

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 (即 ^ l) form 提要字符作为空格; 许多工具将这些字符作为页面分隔符,因此您可以使用它们来分隔文件相关部分的页面。注意,一些编辑器和基于 web 的代码查看器可能无法将 control-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 (在 Python 2中)或 UTF-8(在 Python 3中)的文件不应该有编码声明。

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

在标准库中,非默认编码应该仅用于测试目的,或者当注释或文档字符串需要提及包含非 ascii 字符的作者名称时; 否则,使用 x、 u、 u 或 n 转义是在字符串文本中包含非 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 MUST provide a latin transliteration of their names.

对于 Python 3.0及其以上版本,为标准库规定了以下策略(参见 PEP 3131) : 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.:

    进口通常应该单独列出,例如:

    Yes:

    是的:

    import os
    import sys
    

    No:

    答案是:

    import os, sys
    

    It’s okay to say this though:

    不过,这么说也没关系:

    from subprocess import Popen, PIPE
    
  • Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.

    导入总是放在文件的顶部,放在任何模块注释和文档字符串之后,放在模块全局变量和常量之前。

    Imports should be grouped in the following order:

    进口应按以下顺序分类:

    1. standard library imports 标准库导入
    2. related third party imports 关联第三方进口
    3. local application/library specific imports 特定于本地应用程序/库的导入

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

    您应该在每组导入之间放置一个空行。

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

    如果这个拼写引起本地名称冲突,那么拼写它们:

    import myclass
    import foo.bar.yourclass
    

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

    使用 myclass.MyClass 和 foo.bar.YourClass. YourClass。

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

    应该避免通配符导入(从 < module > import *) ,因为它们使名称空间中出现的名称不清楚,混淆了读取器和许多自动化工具。通配符导入有一个可以防御的用例,即将内部接口作为公共 API 的一部分重新发布(例如,使用可选加速器模块的定义覆盖接口的纯 Python 实现,并且事先不知道哪些定义将被覆盖)。

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

    以这种方式重新发布名称时,下面关于公共接口和内部接口的准则仍然适用。

Module level dunder names 模块级别 dunder 名称

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

模块级别“ dunders”(即带有两个前导和两个后跟的下划线的名称) ,例如 _all author version _,等等,应该放在模块文档字符串之后,但是除了从 _ future _ imports 之外的任何导入语句之前。Python 规定 future-imports 必须出现在除 docstring 之外的任何其他代码之前。

For example:

例如:

"""This is the example module.

This module does stuff.
"""

from __future__ import barry_as_FLUFL

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

import os
import sys

String Quotes 字符串引号

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

在 Python 中,单引号字符串和双引号字符串是相同的。这个 PEP 并没有对此提出建议。选择一个规则并坚持下去。但是,当字符串包含单引号或双引号字符时,请使用另一个引号以避免在字符串中出现反斜杠。它提高了可读性。

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

对于三引号字符串,始终使用双引号字符,以便与 PEP 257中的 docstring 约定保持一致。

Whitespace in Expressions and Statements 表达式和语句中的空格

Pet Peeves 宠物怪

Avoid extraneous whitespace in the following situations:

在以下情况下避免使用无关的空格:

  • Immediately inside parentheses, brackets or braces:

    括号、方括号或大括号内:

    Yes:

    是的:

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

    No:

    答案是:

    spam( ham[ 1 ], { eggs: 2 } )
    
  • Between a trailing comma and a following close parenthesis:

    在后面的逗号和括号之间:

    Yes:

    是的:

    foo = (0,)
    

    No:

    答案是:

    bar = (0, )
    
  • Immediately before a comma, semicolon, or colon:

    在逗号、分号或冒号之前:

    Yes:

    是的:

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

    No:

    答案是:

    if x == 4 : print x , y ; x , y = y , x
    
  • However, in a slice the colon acts like a binary operator, and should have equal amounts on either side (treating it as the operator with the lowest priority). In an extended slice, both colons must have the same amount of spacing applied. Exception: when a slice parameter is omitted, the space is omitted.

    但是,在切片中,冒号的作用类似于二进制运算符,两边的数量应该相等(将其视为优先级最低的运算符)。在扩展切片中,两个冒号应用的间距必须相同。异常: 当片参数被省略时,空格也被省略。

    Yes:

    是的:

    ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:]
    ham[lower:upper], ham[lower:upper:], ham[lower::step]
    ham[lower+offset : upper+offset]
    ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
    ham[lower + offset : upper + offset]
    

    No:

    答案是:

    ham[lower + offset:upper + offset]
    ham[1: 9], ham[1 :9], ham[1:9 :3]
    ham[lower : : upper]
    ham[ : upper]
    
  • Immediately before the open parenthesis that starts the argument list of a function call:

    在函数调用的参数列表的开括号前面:

    Yes:

    是的:

    spam(1)
    

    No:

    答案是:

    spam (1)
    
  • Immediately before the open parenthesis that starts an indexing or slicing:

    在开始索引或切片的开括号之前:

    Yes:

    是的:

    dct['key'] = lst[index]
    

    No:

    答案是:

    dct ['key'] = lst [index]
    
  • More than one space around an assignment (or other) operator to align it with another.

    赋值操作符(或其他)周围的多个空格,以使其与另一个操作符对齐。

    Yes:

    是的:

    x = 1
    y = 2
    long_variable = 3
    

    No:

    答案是:

    x             = 1
    y             = 2
    long_variable = 3
    

Other Recommendations 其他建议

  • Avoid trailing whitespace anywhere. Because it’s usually invisible, it can be confusing: e.g. a backslash followed by a space and a newline does not count as a line continuation marker. Some editors don’t preserve it and many projects (like CPython itself) have pre-commit hooks that reject it.

  • 在任何地方都避免拖尾空格。因为它通常是不可见的,所以它可能会令人困惑: 例如,一个反斜杠后面跟着一个空格,一个换行符不能算作一个行延续标记。有些编辑器没有保留它,许多项目(比如 CPython 本身)有提前提交的钩子来拒绝它。

  • 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,is,not) ,Booleans (and,or,not).

  • If operators with different priorities are used, consider adding whitespace around the operators with the lowest priority(ies). Use your own judgment; however, never use more than one space, and always have the same amount of whitespace on both sides of a binary operator.

    如果使用不同优先级的操作符,请考虑在优先级最低的操作符(ies)周围添加空白。你可以自己判断; 但是,不要使用多个空格,并且二进制运算符两边的空格总是相同的。

    Yes:

    是的:

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

    No:

    答案是:

    i=i+1
    submitted +=1
    x = x * 2 - 1
    hypot2 = x * x + y * y
    c = (a + b) * (a - b)
    
  • Don’t use spaces around the = sign when used to indicate a keyword argument or a default parameter value.

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

    Yes:

    是的:

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

    No:

    答案是:

    def complex(real, imag = 0.0):
        return magic(r = real, i = imag)
    
  • Function annotations should use the normal rules for colons and always have spaces around the -> arrow if present. (See Function Annotations below for more about function annotations.)

    函数注释应该使用冒号的普通规则,如果存在,则始终在-> 箭头周围留有空格。(更多关于函数注释的信息,请参阅下面的函数注释。)

    Yes:

    是的:

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

    No:

    答案是:

    def munge(input:AnyStr): ...
    def munge()->PosInt: ...
    
  • When combining an argument annotation with a default value, use spaces around the = sign (but only for those arguments that have both an annotation and a default).

    当将一个参数注释与一个默认值相结合时,在 = 符号周围使用空格(但仅限于那些既有注释又有默认值的参数)。

    Yes:

    是的:

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

    No:

    答案是:

    def munge(input: AnyStr=None): ...
    def munge(input: AnyStr, limit = 1000): ...
    
  • Compound statements (multiple statements on the same line) are generally discouraged.

    复合语句(在同一行上有多个语句)通常是不被提倡的。

    Yes:

    是的:

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

    Rather not:

    当然不是:

    if foo == 'blah': do_blah_thing()
    do_one(); do_two(); do_three()
    
  • While sometimes it’s okay to put an if/for/while with a small body on the same line, never do this for multi-clause statements. Also avoid folding such long lines!

    虽然有时可以将一个 if/for/While 与一个小的 body 放在同一行上,但是对于多子句语句永远不要这样做。还要避免折叠这么长的线!

    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. 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 sentences, 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 them, and are indented to the same level as that code. Each line of a block comment starts with a # and a single space (unless it is indented text inside the comment).

块注释通常应用于其后的一些(或全部)代码,并缩进到与该代码相同的级别。块注释的每一行都以 # 和一个空格开头(除非注释内部有缩进文本)。

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

块注释中的段落由一行包含 # 的行隔开。

Inline Comments 嵌入式评论

Use inline comments sparingly.

谨慎地使用内联注释。

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

内联注释是与语句在同一行上的注释。内联注释与语句之间至少应该有两个空格分隔。它们应该以 # 和一个单独的空格开始。

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

行内评论是不必要的,如果它们陈述了显而易见的事实,那么它们实际上是分散注意力的。

Don’t do this:

不要这样做:

x = x + 1                 # Increment x

But sometimes, this is useful:

但有时候,这是有用的:

x = x + 1                 # Compensate for border

Documentation Strings 文档字符串

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

用于编写好的文档字符串的约定(也称为“ docstrings”)在 PEP 257中得到了永生。

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

  • 为所有公共模块、函数、类和方法编写文档字符串。文档字符串对于非公共方法是不必要的,但是您应该有一个描述该方法的功能的注释。这个注释应该出现在 def 行之后。

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

    PEP 257描述了良好的文档字符串约定。注意,最重要的是,多行文档字符串的结尾应该单独放在一行上,例如:

    """Return a foobang
    
    Optional plotz says to frobnicate the bizbaz first.
    """
    
  • For one liner docstrings, please keep the closing """ on the same line.

  • 对于一行的文档字符串,请在同一行保留结束符“”。

Naming Conventions 命名约定

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

Python 库的命名约定有点混乱,所以我们永远不会得到完全一致的命名标准——尽管如此,下面是目前推荐的命名标准。新的模块和包(包括第三方框架)应该按照这些标准编写,但是如果现有的库具有不同的风格,则首选内部一致性。

Overriding Principle 凌驾性原则

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

作为 API 的公共部分对用户可见的名称应该遵循反映用法而不是实现的约定。

Descriptive: Naming Styles 描述性: 命名风格

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

有很多不同的命名方式。这有助于识别所使用的命名风格,与它们的用途无关。

The following naming styles are commonly distinguished:

下列命名方式通常是不同的:

  • b (single lowercase letter) (一个小写字母)
  • B (single uppercase letter) (单个大写字母)
  • lowercase
  • lower_case_with_underscores
  • UPPERCASE
  • UPPER_CASE_WITH_UNDERSCORES
  • CapitalizedWords (or CapWords, CamelCase5, StudlyCaps)
  • 大写的 words (或者 CapWords,CamelCase5,StudlyCaps)
  • mixedCase (differs from CapitalizedWords by initial lowercase character!)
  • mixedCase (与大写 word 的区别在于首字母的小写字母!)
  • 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 中使用缩写时,将缩写的所有字母大写。

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

还有一种风格是使用一个短的唯一前缀将相关名称组合在一起。这在 Python 中并不常用,但是为了完整起见提到了它。例如,os.stat ()函数返回一个元组,该元组的项通常具有诸如 st _ mode、 st _ size、 st _ mtime 等名称。(这样做是为了强调与 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.

  • 单个 _ 前导 _ 下划线: 弱“内部使用”指示符。例如,从 m import * 不导入名称以下划线开头的对象。

  • single_trailing_underscore_: used by convention to avoid conflicts with Python keyword, e.g.:

    约定使用 single _ trailing _ underline _: 来避免与 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).

  • _ double _ leading _ underline: 当命名一个 class 属性时,调用名称改动(在类 FooBar 中,_ boo 变成 _ FooBar _ boo; 见下面)。

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

  • _ double _ leading _ and _ trailing _ underline _: “ magic”对象或属性,位于用户控制的名称空间中。例如 init,import 或 file。永远不要发明这样的名称,只使用文档中记录的名称。

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’(小写字母 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 PEP 3131.

标准库中使用的标识符必须是与 ASCII 兼容的,如 PEP 3131的策略部分所述。

Package and Module Names 包和模块名称

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

模块应该有简短的全小写名称。如果下划线提高了可读性,则可以在模块名称中使用下划线。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 PEP 484 should normally use CapWords preferring short names: T, AnyStr, Num. It is recommended to add suffixes _co or _contra to the variables used to declare covariant or contravariant behavior correspondingly. Examples

PEP 484中引入的类型变量的名称通常应该使用 CapWords,而更倾向于使用简短的名称: t,AnyStr,努姆。建议在用于相应地声明协变或逆变行为的变量中添加后缀 _ 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”).

为通过 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 prevailing 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 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.)

如果函数参数的名称与保留关键字冲突,通常最好附加一个尾部下划线,而不是使用缩写或拼写错误。因此,课程比课程更好。(或许使用同义词来避免这种冲突更好。)

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 就不能访问它。一般来说,双前导下划线应该只用于避免在被子类化的类中与属性发生名称冲突。

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.

常量通常在模块级别定义,并用所有大写字母书写,用下划线分隔单词。例如 MAX _ overflow 和 TOTAL。

Designing for inheritance 为继承而设计

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

始终决定类的方法和实例变量(统称为“属性”)应该是公共的还是非公共的。如果有疑问,那就选择非公开的,因为公开比非公开更容易。

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

公共属性是那些您希望类中不相关的客户端使用的属性,并承诺避免向后不兼容的更改。非公共属性是那些不打算被第三方使用的属性; 您不能保证非公共属性不会被更改或者甚至被删除。

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

这里我们不使用术语“ 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”)的属性。有些类被设计为从其继承,以扩展或修改类行为的某些方面。在设计这样的类时,要注意明确决定哪些属性是公共的,哪些属性是子类 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.

    对于简单的公共数据属性,最好只公开属性名,不要使用复杂的 accessor/mutator 方法。请记住,如果您发现一个简单的数据属性需要增强函数行为,那么 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 _ () ,不那么方便。然而,名称改名算法有很好的文档记录,并且很容易手动执行。

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

    注意3: 不是每个人都喜欢名字乱改。尽量平衡避免意外名称冲突的需要和高级呼叫者可能使用的名称冲突。

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 _ set,内部接口(包、模块、类、函数、属性或其他名称)仍然应该以单个前导下划线作为前缀。

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 _ module,该模块从子模块公开功能。

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.

    例如,对于 a + = b 或 a = a + b 形式的语句,不要依赖于 CPython 对就地字符串连接的高效实现。这种优化甚至在 CPython 中也是很脆弱的(它只适用于某些类型) ,并且在所有不使用重新计数的实现中都不存在。在库的性能敏感部分,“。应该使用 join ()表单。这将确保串联在各种实现之间以线性时间发生。

  • Comparisons to singletons like None should always be done with is or is not, never the equality operators.

    与像 None 应该总是用 is 或 is not 这样的单例对比,而不是用相等运算符。

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

    另外,当你真正的意思是如果 x 不是 None 时要注意写 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。虽然两种表达方式在功能上是相同的,但前者更具可读性,更受欢迎。

    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 () decorator 提供了一个工具来生成缺失的比较方法。

    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.

    PEP 207表明自反性规则是由 Python 承担的。因此,解释器可以将 y > x 与 x < y 交换,将 y > = x 与 x < = y 交换,并且可以交换 x = = y 和 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.

    适当地使用异常链。在 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).

    在故意替换内部异常时(在 Python 2中使用“ raise x”或在 Python 3.3 + 中使用“ raise x from 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 ValueError (‘ message’)。

    The latter form is not legal Python 3 syntax.

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

    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.

    使用括号的形式还意味着,当异常参数很长或包含字符串格式时,由于包含括号,您不需要使用行继续字符。

  • When catching exceptions, mention specific exceptions whenever possible instead of using a bare except: clause.

    在捕获异常时,尽可能提到特定的异常,而不要使用 bare except: 子句。

    For example, use:

    例如,使用:

    try:
        import platform_specific_module
    except ImportError:
        platform_specific_module = None
    

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

    一个 bare except: 子句将捕获 SystemExit 和 KeyboardInterrupt 异常,使得使用 Control-C 中断程序更加困难,并且可以掩盖其他问题。如果您想捕获所有标志程序错误的异常,请使用 Exception: (bare except 等同于 except BaseException:)。

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

    一个很好的经验法则是把单独的‘ except’从句限制在两种情况下使用:

    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. 如果异常处理程序将打印出来或记录回溯; 至少用户将知道发生了错误。
    3. 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.
    4. 如果代码需要做一些清理工作,但是随后让异常通过 raise 向上传播。试试看... 最终可能是处理这个案子的更好方法。
  • When binding caught exceptions to a name, prefer the explicit name binding syntax added in Python 2.6:

    当绑定捕捉到名称的异常时,更喜欢 Python 2.6中添加的显式名称绑定语法:

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

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

    这是 Python 3中唯一支持的语法,并避免了与旧的基于逗号的语法相关的歧义问题。

  • When catching operating system errors, prefer the explicit exception hierarchy introduced in Python 3.3 over introspection of errno values.

  • 在捕获操作系统错误时,更喜欢 Python 3.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 子句限制在所需代码的绝对最小量。同样,这样可以避免掩盖漏洞。

    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. For example:

    只要上下文管理器执行的任务不是获取和释放资源,就应该通过单独的函数或方法调用它们。例如:

    Yes:

    是的:

    with conn.begin_transaction():
        do_stuff_in_transaction(conn)
    

    No:

    答案是:

    with conn:
        do_stuff_in_transaction(conn)
    

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

    后一个例子没有提供任何信息来表明 _ enter _ 和 _ exit _ 方法除了在事务之后关闭连接之外还在做其他事情。在这种情况下,明确是很重要的。

  • Be consistent in return statements. Either all return statements in a function should return an expression, or none of them should. If any return statement returns an expression, any return statements where no value is returned should explicitly state this as return None, and an explicit return statement should be present at the end of the function (if reachable).

    在返回语句中保持一致。要么函数中的所有返回语句都应该返回一个表达式,要么它们都不应该返回。如果任何 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 backward compatibility with Pythons older than 2.0 is required.

    字符串方法总是快得多,并且与 unicode 字符串共享相同的 API。如果需要使用年龄大于2.0的向下兼容,则重写此规则。

  • Use ''.startswith() and ''.endswith() instead of string slicing to check for prefixes or suffixes.

    使用“ . startswith ()和”. endswith ()代替字符串切片来检查前缀或后缀。

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

    Startswith ()和 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 字符串!在 Python 2中,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)

    注意,在 Python 3中,unicode 和基本字符串不再存在(只有 str) ,并且一个 bytes 对象不再是一种字符串(而是一个整数序列)

  • For sequences, (strings, lists, tuples), use the fact that empty sequences are false:

    对于序列(字符串、列表、元组) ,使用空序列为 false 这一事实:

    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.

  • 不要编写依赖于重要尾随空格的字符串文本。这样的尾随空格在视觉上是难以区分的,一些编辑器(或者更近一些的 reindenton. 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.)

  • 为了向前兼容,Python 3代码中的函数注释最好使用 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.

  • 然而,在 stdlib 之外,现在鼓励在 PEP 484规则内进行实验。例如,用 PEP 484风格的类型注释标记一个大型的第三方库或应用程序,评估添加这些注释是否容易,并观察它们的存在是否增加了代码的可理解性。

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

  • 不想使用类型检查器的用户可以随意忽略它们。但是,第三方库包的用户可能希望对这些包运行类型检查器。为此,PEP 484建议使用存根文件: 。类型检查器优先读取相应的 pyi 文件。Py 文件。存根文件可以与库一起分发,也可以通过类型化的 repo 6单独分发(需要库作者的许可)。

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

    对于需要向后兼容的代码,可以以注释的形式添加类型注释。参见 PEP 4847的相关章节。


Footnotes 脚注

  1. PEP 7, Style Guide for C Code, van Rossum

    7,Style Guide for c Code,van Rossum something

  2. Barry’s GNU Mailman style guide http://barry.warsaw.us/software/STYLEGUIDE.txt

    的 GNU Mailman 风格指南 http://Barry.warsaw.us/software/styleguide.txt↩

  3. 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 的上下文中,这个术语用于描述这样一种样式,即圆括号语句的开始括号是行的最后一个非空格字符,后面的行被缩进直到结束括号。Something

  4. Donald Knuth's The TeXBook, pages 195 and 196.

    唐纳德 · 克努斯的《文本书》 ,第195和196页

  5. http://www.wikipedia.com/wiki/CamelCase

  6. Typeshed repo https://github.com/python/typeshed

    排版回收 https://github.com/python/Typeshed↩

  7. Suggested syntax for Python 2.7 and straddling code https://www.python.org/dev/peps/pep-0484/#suggested-syntax-for-python-2-7-and-straddling-code

    建议的 Python 2.7语法和跨代码 https://www.Python.org/dev/peps/pep-0484/#Suggested-syntax-for-Python-2-7-and-straddling-code↩

Copyright 版权所有

This document has been placed in the public domain.

这份文件已被公开。

Fork me on GitHub ×拖拽到此处 And drag it here图片将完成下载Image will be downloaded 彩云小译 刚刚0本网页由彩云小译翻译

分类:

后端

标签:

后端

作者介绍

逸之
V1