Python创始人Guido van Rossum曾说:“Code is read much more often than it is written”。那么,如何写出可读性高的Python代码?本文为您介绍PEP 8——Python代码编写规范。
1 代码布局1.1 源文件编码
Python 3核心的发行版中的代码使用的是UTF-8编码(Python 2中则使用ASCII编码);在Python3.0及以上的版本中规定:Python标准库中的所有标识符务必使用纯ASCII标识符,并尽可能使用英文单词;除了在测试用例及作者名字可使用非ASCII外,字符串文字和注释也必须使用ASCII。(详见PEP 3131)
PEP为提供了显式声明Python源文件编码的语法,常用的两种如下所示,其核心需满足正则表达式
^[ \t\f]*#.*?coding[:=][ \t]*([-_.a-zA-Z0-9]+)
,以提供正确的编码信息给Python解释器。
# coding=
1.2 导入模块
模块导入总是放在文件的顶部,在模块注释和文档字符串之后;通常每行导入一个模块;并按照如下顺序分组:标准库、相关第三方库、本地应用程序或库,在每组间放置空格以进行区分。
另外,推荐使用绝对导入,在系统配置错误时能够提供更加清晰地错误信息;同时尽量避免使用通配符导入"from import * ",易将未知的变量名引入命名空间进而引发混乱。
还有一类特殊名称需要放置在导入模块部分,即名称前后具有两个下划线的名称(如
all__, __author__, __version
等,也被成为模块级Dunder名称),需要放置在文档字符串之后,除from __future__ import *
之外的导入语句之前。以下是一个模块导入部分的示例:
# 文档字符串,将在后文介绍
1.3 单行长度
PEP 8建议将单行限制为79个字符,用户可以将多个文件彼此相邻打开以进行对比查看。但保持语句始终小于79字符是不可能的,Python中的括号、方括号和花括号提供了隐含的行连续性,反斜线提供显示的行连续。
# 隐含的行连续
1.4 代码缩进
Python中的每个缩进级别使用4个空格,以下为基础缩进用法示例:
# 与括号、方括号、花括号分隔符垂直对齐
1.5 制表符缩进 or 空格缩进?
空格是缩进的首选方法,制表符仅应用于已经使用制表符缩进的代码保持一致。
Python3不允许混合使用制表符和空格进行缩进。对于混合使用的Python2代码应转换为仅使用空格,否则当使用-t选项调用Python2命令行解释器时会发出混用警告,-tt选项则将警告变为错误。
1.6 二元运算符与换行符
换行符应该在二元运算符之前还是之后的问题严重的影响代码的可读性,数学家Kunth提出遵循数学惯例的样式:
# 正确:方便的将运算符与运算对象匹配
1.7 空行的使用
函数和类定义用两个空行环绕;
类内部的方法定义用单个空行环绕;
函数中使用空白行指示代码逻辑;
额外的空行用于分割相关功能组;
需注意Python可使用换页符(control-L, ^L)作为空格,其他编辑器可能无法识别。
所有命名应避免使用小写字母l,大写字母O, I作为单字符变量名称,易与数字0,1产生混淆。其他常见的命名规则如下表所示:
块注释:适用于其之后的代码,以#和一个空格开头,并缩进到与代码相同的级别。可用含单个#的行分割注释段落。
内嵌注释:适用于单行代码,以#和一个空格开头,与语句在同一行且间隔至少两个空格。不要用于意义显而易见的代码行。
文档字符串:PEP 257规定应为所有的公共模块、函数、类和方法编写文档字符串;对非公共方法不是必须的,但可以在def行之后描述该方法的作用。其用三个双引号进行表示,多行文档字符串中"""应单独位于一行,单行文档字符串可与字符串位于一行。
4.1 字符串引号
在Python中,单引号字符串与双引号字符串是相同的,我们可以选择喜欢的方式使用。但当字符串中包含单引号或双引号字符时,需要用另一个以避免使用反斜杠转义符,提高可读性。三引号字符串则应该使用双引号字符以与PEP 257中的文档字符串约定一致。
4.2 结尾逗号
结尾的逗号的通常是可以选择的,在仅有一个元素的元组中是必需的,PEP 8建议将其用括号括起来。
在版本控制系统中,结尾逗号能够极大的方便我们扩展参数或导入项的列表,可以将参数或值单独放在一行上,始终添加结尾的逗号。
# 单元素元组
4.3 表达式和语句中的空白
始终在二元操作符前后使用1个空格环绕;
如果使用优先级不同的运算符,优先在优先级最低的运算符两边添加空格;
避免使用末尾空格,如在反斜杠后跟空格不能作为行继续标记;
以下情况应避免使用多余的空格:
# 紧跟括号、方括号、大括号
5
编程建议
应该用更为普遍的方式编写代码,而不仅仅依赖某一Python实现(PyPy, Jython, Cython等)。如CPython中常用的字符串连接语句a += b或者a = a + b,应该用' '.join()确保字符串连接的准确性。
与单例(如None)比较时应使用is 或者 not,不要使用=运算符。
尽管is not运算符与not ... is运算的功能是相同的,但is not可读性更高,更鼓励使用。
if foo
当实现自定义的排序操作时,最好实现所有六个操作(
__eq__, __ne__, __lt__, __le__, __gt__, __ge__
)。不要使用==运算符对布尔值与True或False进行比较。
if greeting:
始终使用def语句而不是lambda表达式实现函数标识符绑定,def语句在错误回溯中更为有用,lambda表达式在嵌入更大的表达式中时较为常用。
def f(x):
使用try/except语句时,将try部分代码限制为最可能出现错误的代码块,而不是将太宽泛的代码放入,缩小范围有助于错误发现。
打开本地文件使用with语句实现自动的关闭清理,try/except语句也可以接受。
函数中的return语句应该保持一致,要么都返回表达式,要么都不返回。
# 正确
使用"".startswith()和"".endswith()代替字符串切片来检查字符串前缀或后缀。
使用isinstance()来比较对象类型,而不是直接比较。
# 正确
Python中空序列(字符串、列表、元组)为False。
if seq:
不要使用包含尾随空格的字符串文字,字符串末尾的空格在视觉上难以区分,甚至会被某些编辑器去掉,''.strip()函数在字符串处理中很常用。
不推荐在try/finally语句的finally部分包含return/break/continue,这将隐含取消except部分的异常。
Autopep8是自动将Python代码格式化为符合PEP 8风格的工具之一,它使用pycodestyle工具来检测格式问题并修复,最终将代码自动调整为PEP 8风格。
# 下载安装
打开pycharm,进入File--Settings--Tools--Extends Tools,点击加号,配置如下项:
- Name: autopep8 (可随意)
配置完成后就能够在右键菜单External Tools中使用,自动将您的代码调整为PEP 8风格。
版权所有,转载请注明出处