内容 介绍本文档提供了Python代码的编码约定,包括主Python发行版中的标准库。请参阅Python的C实现中描述C代码样式指南的配套信息PEP [1]。 本文和PEP 257(Docstring约定)改编自Guido的原始Python风格指南文章,并附有Barry的风格指南[2]。 随着时间的推移,随着语言本身的变化,过去的约定被淘汰,这种风格指南随着时间的推移而不断发展。 许多项目都有自己的编码风格指南。如果发生任何冲突,此类项目特定指南优先于该项目。 愚蠢的一致性是小思想的大人物Guido的一个关键见解是,代码的读取频率远高于编写代码。此处提供的准则旨在提高代码的可读性,并使其在各种Python代码中保持一致。正如PEP 20所说,“可读性很重要”。 风格指南是关于一致性的。与此风格指南的一致性非常重要。项目内的一致性更为重要。一个模块或功能内的一致性是最重要的。 但是,知道何时不一致 - 有时风格指南建议不适用。如有疑问,请使用您的最佳判断。查看其他示例并确定最佳效果。并且不要犹豫,不要问! 特别是:不要为了遵守这个PEP而破坏向后兼容性! 忽略特定指南的其他一些好理由:
代码布局缩进每个缩进级别使用4个空格。 延续线应垂直对齐包装元素,使用Python的隐含线连接括号,括号和大括号,或使用悬挂缩进 [7]。使用悬挂式凹痕时,应考虑以下因素; 第一行应该没有参数,应该使用进一步的缩进来明确区分自己作为延续线。 是: #与开口分隔符对齐。 foo = long_function_name(var_one,var_two, var_three,var_four) #包括更多缩进以区别于其余部分。 def long_function_name( var_one,var_two,var_three, var_four): 打印(var_one) #悬挂缩进应该添加一个级别。 foo = long_function_name( var_one,var_two, var_three,var_four) 没有: #不使用垂直对齐时禁止第一行上的参数。 foo = long_function_name(var_one,var_two, var_three,var_four) #由于缩进无法区分,因此需要进一步缩进。 def long_function_name( var_one,var_two,var_three, var_four): 打印(var_one) 对于连续线,4空间规则是可选的。 可选的: #悬挂缩进*可以*缩进到4个空格以外的其他位置。 foo = long_function_name( var_one,var_two, var_three,var_four) 当if语句的条件部分长到足以要求它跨多行写入时,值得注意的是两个字符关键字(即if)的组合,加上单个空格,加上一个左括号创建一个自然的多行条件的后续行的4空格缩进。这可能与嵌套在if -statement中的缩进代码集产生视觉冲突,该代码集自然也会缩进到4个空格。该PEP没有明确地说明如何(或是否)进一步在视觉上将这些条件线与if- statement 内的嵌套套件区分开来。在这种情况下可接受的选择包括但不限于: #没有额外的缩进。 if(this_is_one_thing和 that_is_another_thing): 做一点事() #添加注释,这将在编辑器中提供一些区别 #支持语法高亮显示。 if(this_is_one_thing和 that_is_another_thing): #由于这两个条件都属实,我们可以讨厌。 做一点事() #在条件连续行上添加一些额外的缩进。 if(this_is_one_thing 和that_is_another_thing): 做一点事() (另请参阅下面关于是否在二元运算符之前或之后中断的讨论。) 多行结构上的右括号/括号/括号可以在列表最后一行的第一个非空白字符下排列,如下所示: my_list = [ 1,2,3, 4,5,6, ] result = some_function_that_takes_arguments( ''a'',''b'',''c'', ''d'',''e'',''f'', ) 或者它可以排在启动多线结构的线的第一个字符下面,如: my_list = [ 1,2,3, 4,5,6, ] result = some_function_that_takes_arguments( ''a'',''b'',''c'', ''d'',''e'',''f'', ) 标签或空格?空格是首选的缩进方法。 选项卡应仅用于与已使用选项卡缩进的代码保持一致。 Python 3不允许混合使用制表符和空格来缩进。 使用制表符和空格的混合缩进的Python 2代码应该转换为仅使用空格。 当使用-t选项调用Python 2命令行解释器时,它会发出有关非法混合制表符和空格的代码的警告。使用-tt时,这些警告会出错。强烈推荐这些选项! 最大线长将所有行限制为最多79个字符。 对于具有较少结构限制(文档字符串或注释)的长文本块,行长度应限制为72个字符。 限制所需的编辑器窗口宽度使得可以并排打开多个文件,并且在使用在相邻列中显示两个版本的代码审查工具时可以正常工作。 大多数工具中的默认包装会破坏代码的可视化结构,使其更难理解。选择限制是为了避免在窗口宽度设置为80的情况下包装在编辑器中,即使工具在包装线条时在最终列中放置标记字形。某些基于Web的工具可能根本不提供动态换行。 有些团队强烈倾向于更长的线路长度。对于专门或主要由可以就此问题达成一致的团队维护的代码,可以将标称行长度从80个字符增加到100个字符(有效地将最大长度增加到99个字符),前提是评论和文档字符串仍然包装72个字符。 Python标准库是保守的,需要将行限制为79个字符(文档字符串/注释限制为72个)。 包装长行的首选方法是在括号,括号和括号内使用Python隐含的行继续。通过在括号中包装表达式,可以在多行上分割长行。这些应该优先使用反斜杠来继续行。 反斜杠有时可能仍然合适。例如,long,multiple with -statements不能使用隐式延续,因此可以接受反斜杠: 打开(''/ path / to / some / file / you / want / to / read'')as file_1,\ 打开(''/ path / to / some / file / being / written'',''w'')作为file_2: file_2.write(file_1.read()) (参见前面关于多行if语句的讨论,以进一步思考这种带有 -statements的多行缩进。) 另一个这样的情况是使用断言语句。 确保适当地缩进续行。 应该在二元运算符之前或之后换行吗?几十年来,推荐的风格是在二元运算符之后打破。但这会以两种方式损害可读性:操作员倾向于分散在屏幕上的不同列上,并且每个操作符都会从其操作数移到前一行。在这里,眼睛必须做额外的工作来分辨哪些项目被添加以及哪些项目被减去: #No:运营商远离他们的操作数 收入=(gross_wages + taxable_interest + (股息 - qualified_dividends) - ira_deduction - student_loan_interest) 为了解决这个可读性问题,数学家和他们的出版商遵循相反的惯例。Donald Knuth在他的计算机和排版系列中解释了传统规则:“虽然段落中的公式总是在二元操作和关系之后中断,但显示的公式总是在二元操作之前中断” [3]。 遵循数学传统通常会产生更易读的代码: #Yis:易于将操作符与操作数匹配 收入=(gross_wages + taxable_interest +(股息 - qualified_dividends) - ira_deduction - student_loan_interest) 在Python代码中,只要约定在本地一致,就允许在二元运算符之前或之后中断。对于新代码,建议使用Knuth的样式。 空白行使用两个空行环绕顶级函数和类定义。 类中的方法定义由单个空行包围。 可以使用额外的空白行(谨慎地)来分离相关功能组。在一堆相关的单行(例如,一组虚拟实现)之间可以省略空行。 在函数中使用空行,谨慎地指示逻辑部分。 Python接受control-L(即^ L)换页符作为空格; 许多工具将这些字符视为页面分隔符,因此您可以使用它们来分隔文件相关部分的页面。请注意,某些编辑器和基于Web的代码查看器可能无法将control-L识别为换页符,并且会在其位置显示另一个字形。 源文件编码核心Python发行版中的代码应始终使用UTF-8(或Python 2中的ASCII)。 使用ASCII(在Python 2中)或UTF-8(在Python 3中)的文件不应具有编码声明。 在标准库中,非默认编码应仅用于测试目的,或者当注释或文档字符串需要提及包含非ASCII字符的作者名称时; 否则,使用\ x, \ u,\ U或\ N转义是在字符串文字中包含非ASCII数据的首选方法。 对于Python 3.0及更高版本,标准库规定了以下策略(参见PEP 3131):Python标准库中的所有标识符必须使用仅ASCII标识符,并且应尽可能使用英语单词(在许多情况下,缩写和技术)使用的术语不是英语)。此外,字符串文字和注释也必须是ASCII格式。唯一的例外是(a)测试非ASCII功能的测试用例,以及(b)作者姓名。名称不是基于拉丁字母(latin-1,ISO / IEC 8859-1字符集)的作者必须在此字符集中提供其名称的音译。 鼓励全球受众的开源项目采用类似的政策。 进口
模块级别Dunder名称模块级“dunders”(即名称具有两个前缘和两个纵下划线)如__all__,__author__,__version__等应被放置在模块文档字符串之后,但在任何导入语句以外 从__future__进口。Python要求future-imports必须在除docstrings之外的任何其他代码之前出现在模块中: “”这是示例模块。 这个模块做的东西。 “”” 来自__future__ import barry_as_FLUFL __all__ = [''a'',''b'',''c''] __version__ =''0.1'' __author__ =''红衣主教Biggles'' 进口口 导入系统 字符串引号在Python中,单引号字符串和双引号字符串是相同的。该PEP不会对此提出建议。选择规则并坚持下去。但是,当字符串包含单引号或双引号字符时,请使用另一个字符串以避免字符串中出现反斜杠。它提高了可读性。 对于三引号字符串,始终使用双引号字符与PEP 257中的docstring约定一致。 表达式和语句中的空格宠物皮皮鬼在以下情况下避免无关的空格:
其他建议
何时使用尾随逗号尾随逗号通常是可选的,除了它们在制作一个元素的元组时是必需的(在Python 2中它们具有print语句的语义)。为清楚起见,建议将后者括在(技术上冗余的)括号中。 是: FILES =(''setup.cfg'',) 好的,但令人困惑: FILES =''setup.cfg'', 当尾随逗号是多余的时,它们通常在使用版本控制系统时有用,当预期值列表,参数或导入项目随时间延长时。模式是将每个值(等)单独放在一行上,始终添加一个尾随逗号,并在下一行添加右括号/括号/括号。但是,在与结束分隔符相同的行上使用尾随逗号是没有意义的(除了上面的单例元组的情况)。 是: 文件= [ ''setup.cfg'', ''tox.ini'', ] 初始化(文件, 错误=真, ) 没有: FILES = [''setup.cfg'',''tox.ini'',] 初始化(FILES,错误= True,) 注释与代码相矛盾的评论比没有评论更糟糕。始终优先考虑在代码更改时保持评论的最新状态! 评论应该是完整的句子。第一个单词应该大写,除非它是一个以小写字母开头的标识符(永远不会改变标识符的情况!)。 块注释通常由完整句子构成的一个或多个段落组成,每个句子以句点结束。 除了最后一句之外,你应该在句子结束时间之后的多句话评论中使用两个空格。 写英文时,请遵循Strunk和White。 来自非英语国家的Python程序员:请用英语撰写您的评论,除非您120%确信不会说不懂您语言的人不会阅读该代码。 内联评论谨慎使用内联评论。 内联注释是与语句在同一行上的注释。内联注释应该与语句至少分隔两个空格。它们应该以#和单个空格开头。 内联注释是不必要的,如果他们说明显的话,实际上会分散注意力。不要这样做: x = x + 1#增量x 但有时,这很有用: x = x + 1#补偿边界 命名约定Python库的命名约定有点混乱,所以我们永远不会完全一致 - 尽管如此,这是目前推荐的命名标准。应该将新模块和包(包括第三方框架)写入这些标准,但是如果现有库具有不同的样式,则首选内部一致性。 压倒一切的原则作为API的公共部分对用户可见的名称应遵循反映使用而非实现的约定。 描述性:命名样式有很多不同的命名方式。它有助于识别正在使用的命名样式,与它们的用途无关。 通常会区分以下命名样式:
还有使用简短唯一前缀将相关名称组合在一起的风格。这在Python中并不常用,但为了完整性而提到它。例如,os.stat()函数返回一个元组,其元素传统上具有st_mode, st_size,st_mtime等名称。(这样做是为了强调与POSIX系统调用struct的字段的对应关系,这有助于程序员熟悉它。) X11库使用前导X来表示其所有公共功能。在Python中,这种样式通常被认为是不必要的,因为属性和方法名称以对象为前缀,函数名称以模块名称为前缀。 此外,还会识别使用前导或尾随下划线的以下特殊形式(这些形式通常可与任何案例约定结合使用):
规定性:命名约定要避免的名字切勿将字符''l''(小写字母el),''O''(大写字母哦)或''I''(大写字母眼睛)用作单个字符变量名称。 在某些字体中,这些字符与数字1和0无法区分。当试图使用''l''时,请使用''L''。 包和模块名称模块应该有简短的全小写名称。如果提高可读性,可以在模块名称中使用下划线。Python包也应该有简短的全小写名称,但不鼓励使用下划线。 当用C或C ++编写的扩展模块具有提供更高级别(例如更多面向对象)的接口的Python模块时,C / C ++模块具有前导下划线(例如_socket)。 班级名称类名通常应使用CapWords约定。 在接口被记录并主要用作可调用的情况下,可以使用函数的命名约定。 请注意,内置名称有一个单独的约定:大多数内置名称是单个单词(或两个单词一起运行),CapWords约定仅用于异常名称和内置常量。 输入变量名称PEP 484中引入的类型变量的名称通常应使用CapWords ,而不是短名称:T,AnyStr,Num。建议将后缀_co或_contra添加到用于相应声明协变或逆变行为的变量中: 从键入导入TypeVar VT_co = TypeVar(''VT_co'',covariant = True) KT_contra = TypeVar(''KT_contra'',contravariant = True) 例外名称因为异常应该是类,所以类命名约定适用于此处。但是,您应该在异常名称上使用后缀“Error”(如果异常实际上是错误)。 全局变量名称(我们希望这些变量仅用于一个模块内。)约定与函数的约定大致相同。 设计为通过M import *使用的模块应该使用__all__机制来防止输出全局变量,或者使用旧的约定为这些全局变量添加下划线(您可能希望这样做以表明这些全局变量是“模块非公开的” “)。 函数和变量名称函数名称应为小写,并根据需要用下划线分隔,以提高可读性。 变量名称遵循与函数名称相同的约定。 只有在已经是主流风格(例如threading.py)的上下文中才允许使用mixedCase,以保持向后兼容性。 函数和方法参数始终使用self作为实例方法的第一个参数。 始终使用cls作为类方法的第一个参数。 如果函数参数的名称与保留关键字冲突,通常最好附加单个尾随下划线而不是使用缩写或拼写损坏。因此class_比clss好。(或许更好的方法是通过使用同义词来避免这种冲突。) 方法名称和实例变量使用函数命名规则:小写,必要时用下划线分隔,以提高可读性。 仅对非公共方法和实例变量使用一个前导下划线。 为避免与子类的名称冲突,请使用两个前导下划线来调用Python的名称修改规则。 Python使用类名来破坏这些名称:如果类Foo具有名为__a的属性,则Foo .__ a无法访问它。(坚持不懈的用户仍然可以通过调用Foo._Foo__a获得访问权限。)通常,双重前导下划线应该仅用于避免与设计为子类的类中的属性发生名称冲突。 注意:关于__names的使用存在一些争议(见下文)。 常量常量通常在模块级别定义,并以全部大写字母书写,下划线分隔单词。示例包括 MAX_OVERFLOW和TOTAL。 设计继承始终决定一个类的方法和实例变量(统称为“属性”)是公共的还是非公共的。如有疑问,请选择非公开; 将公共属性设为非公开更容易公开。 公共属性是指您希望类的无关客户端使用的属性,您承诺避免向后不兼容的更改。非公开属性是指不打算由第三方使用的属性; 您不能保证非公共属性不会更改甚至不会被删除。 我们在这里不使用术语“私有”,因为在Python中没有属性是真正私有的(没有通常不必要的工作量)。 另一类属性是属于“子类API”的属性(通常在其他语言中称为“受保护”)。某些类旨在从中继承,以扩展或修改类的行为方面。在设计这样的类时,请注意明确决定哪些属性是公共的,哪些是子类API的一部分,哪些属性真正只能由基类使用。 考虑到这一点,这是Pythonic指南:
公共和内部接口任何向后兼容性保证仅适用于公共接口。因此,用户能够清楚地区分公共和内部接口是很重要的。 记录的接口被认为是公共的,除非文档明确声明它们是临时的或内部接口免于通常的向后兼容性保证。应假定所有未记录的接口都是内部接口。 为了更好地支持内省,模块应使用__all__属性在其公共API中显式声明名称。将__all__设置 为空列表表示该模块没有公共API。 即使适当地设置__all__,内部接口(包,模块,类,函数,属性或其他名称)仍应以单个前导下划线为前缀。 如果任何包含名称空间(包,模块或类)的内容被视为内部接口,则该接口也被视为内部接口。 应始终将导入的名称视为实现细节。其他模块不能依赖于对这些导入名称的间接访问,除非它们是包含模块的API的显式记录部分,例如os.path或从子模块公开功能的包的__init__模块。 编程建议
功能注释随着PEP 484的接受,功能注释的样式规则正在发生变化。
变量注释PEP 526引入了变量注释。它们的样式建议类似于上面描述的函数注释:
脚注
|
|
来自: 许文强1234 > 《python学习资料》