
1.3 Python编码规范
代码总是要给人看的,尤其是对于大项目而言,可读性往往跟鲁棒性的要求一样高。跟其他语言有所不同的是,Python官方就收录了一套“增强提案”,也就是Python Enhancement Proposal,其中第8个提案就是Python代码风格指导书,足以见得Python对编码规范的重视。
本节会重点介绍PEP 8提案,为写出一手漂亮的Python代码打下基础。本节内容可能需要结合后面章节知识学习。
PEP 8就是Python增强提案8号,标题为Style Guide for Python Code,主要涉及Python代码风格上的一些约定,其中值得一提的是Python标准库遵守的也是这份约定。
由于PEP 8涉及的内容相当多,下面选择一些比较重要的进行讲解。
1.3.1 代码布局
1.空格还是Tab
PEP 8中提到,无论任何时候都应该优先使用空格来对齐代码块,Tab对齐只有在原代码为Tab对齐时才应该使用(出于兼容考虑),同时在Python3中空格和Tab混用是无法执行的。
对于这个问题大部分编辑器或者IDE都有相应选项,可以把Tab自动转换为4个空格,图1-36就是Notepad++中的转换选项。

图1-36 Noptepad++制表符设置
2.缩进对齐
PEP 8中明确了换行对齐的要求。
对于函数调用,如果部分参数换行,应该做到与分隔符垂直对齐,比如:

但是如果是函数定义中全部参数悬挂的话,应该多一些缩进来区别正常的代码块,比如:

在函数调用中对于完全悬挂的参数也是同理,比如:

但是对于if语句,由于if加上空格和左括号构成了四个字符的长度,因此PEP 8对if的换行缩进没有严格的要求,比如下面这三种情况都是完全合法的:


此外,对于用于闭合的右括号、右中括号等有两种合法情况,一种是跟之前最后一行的缩进对齐,比如:

但是也可以放在行首,比如:

此外如果有操作符的话,操作符应该放在每行的行首,因为可以简单地看出对每个操作数的操作是什么,比如:

当然,去记忆这些缩进规则是非常麻烦的,如果浪费过多时间在调整格式上的话就是本末倒置了,之后我们会学习如何自动检查和调整代码,使其符合PEP 8的要求。
3.每行最大长度
在PEP 8中明确约定了每行最大长度应该是79个字符。
之所以这么约定,主要是有三个原因:
● 限制每行的长度意味着在读代码的时候代码不会超出一个屏幕,提高阅读体验。
● 如果一行过长可能是这一行完成的事情太多,为了可读性应该拆成几个更小的步骤。
● 如果仅仅是因为变量名太长或者参数太多,应该按照上述规则换行对齐。
这里要注意的是,还有一种方法可以减少每行的长度,那就是续行符,比如:

虽然with的语法我们还没有提到,不过不影响阅读,只要知道反斜杠在这里表示续行就行了,也就是说这一段代码等价于:

第二种是不是可读性要差很多?这就是限制每行长度的好处。
4.空行
合理的空行可以很大程度上增加代码的段落感,PEP 8对空行有以下规定:
● 类的定义和最外层的函数定义之间应该有2个空行。
● 类的方法定义之间应该有1个空行。类和方法的概念第2章会提到,这里有个印象就可以了。
● 多余的空行可以用来给函数分组,但是应该尽量少用。
● 在函数内使用空行把代码分为多个小逻辑块是可以的,但是应该尽量少用。
5.导入
PEP 8对import(导入)也有相应的规范。
对于单独的模块导入,应该一行一个,比如:

但是如果用from ... import ...,后面的导入内容允许多个并列,比如:

但是应该避免使用∗来导入,比如下面这样是不被推荐的:

此外导入语句应该永远放在文件的开头,同时导入顺序应该为:
● 标准库导入。
● 第三方库导入。
● 本地库导入。
6.字符串
在Python中既可以使用单引号也可以使用双引号来表示一个字符串,因此PEP 8建议在写代码的时候尽量使用同一种分隔符,但是如果在使用单引号字符串的时候要表示单引号,可以考虑混用一些双引号字符串来避免反斜杠转义,进而获得代码可读性的提升。
7.注释
本章开始就接触到了注释的写法,并且自始至终一直在代码示例中使用,足以见得注释对提升代码可读性的重要程度。但是PEP8对注释也提出了要求:
● 和代码矛盾的注释不如不写。
● 注释更应该和代码保持同步。
● 注释应该是完整的句子。
● 除非确保只有和你使用相同语言的人阅读你的代码,否则注释应该用英文书写。
Python中的注释以#开头,分为两类,第一种是跟之前代码块缩进保持一致的块注释,比如:

另一种是行内注释,用至少两个空格和正常代码隔开,比如:

但是PEP8中提到这样会分散注意力,建议只有在必要的时候才使用。
8.文档字符串
文档字符串即Documentation Strings,是一种特殊的多行注释,可以给模块、函数、类或者方法提供详细的说明。更重要的是,文档字符串可以直接在代码中调用,比如:

这样就会输出:

在PyCharm中只要输入三个双引号就可以自动创建一个文档字符串的模板。至于文档字符串的写作约定,PEP8没有提到太多,更多的可以参考PEP257。
9.命名规范
PEP8中提到了Python中的命名约定。在Python中常见的命名风格有以下这些:
● b单独的小写字母。
● B单独的大写字母。
● lowercase全小写。
● lower_case_with_underscores全小写并且带下划线。
● UPPERCASE全大写。
● UPPER_CASE_WITH_UNDERSCORES全大写并且带下划线。
● CamelCase大驼峰。
● camelCase小驼峰。
● Capitalized_Words_With_Underscores带下划线的驼峰。
除了这些命名风格,在特殊的场景还有一些别的约定,这里只挑出一些常用的:
● 避免使用l和o为单独的名字,因为它们很容易被弄混。
● 命名应该是ASCII兼容的,也就是说应该避免使用中文名称,虽然是被支持的。
● 模块和包名应该是全小写并且尽量短的。
● 类名一般采用CameCase这种驼峰式命名。
● 函数和变量名应该是全小写的,下划线只有在可以改善可读性的时候才使用。
● 常量应该是全大写的,下划线只有在可以改善可读性的时候才使用。
有些概念我们还没有学习,可以只做了解。
1.3.2 自动检查调整
PEP8的内容相当详细烦琐,纯手工调整格式显然是要浪费时间的,所以这里介绍两个工具来帮助我们写出符合PEP8要求的代码。
1.pycodestyle
pycodestyle是一个用于检查代码风格是否符合PEP8并且给出修改意见的工具,我们可以通过pip安装它:

安装后,只要在命令行中继续输入:

就可以看到所有的使用方法,这里借用官方给出的一个例子:

其中--show-source表示显示源代码,--show-pep8表示为每个错误显示相应的PEP8具体文本和改进意见,而后面的路径表示要检查的源代码。
2.PyCharm
虽然pycodestyle使用简单,结果提示也清晰明确,但是这个检查不是实时的,而且我们总要额外切出来一个终端去执行指令,这都是不太方便的。这时候可以使用PyCharm。
PyCharm的强大功能之一就是实时的PEP8检查,比如对于上面的例子,在PyCharm中会出现提示,如图1-37所示。
并且我们只要把光标移动到相应位置后,按下Alt+Enter键就可以出现修改建议,如图1-38所示。

图1-37 PyCharm PEP8提示

图1-38 修改建议
选择Optimize imports后可以看到PyCharm把代码格式转换为符合PEP8的样式,如图1-39所示。

图1-39 修改后的代码
所以如果喜欢用简单的文本编辑器书写代码的话,可以使用pycodestyle,但是如果更青睐使用IDE的话,PyCharm的PEP8提示可以在写出漂亮代码的同时节省大量的时间。
特殊地,PyCharm也有一个代码批量格式化快捷键,在全选之后按下〈Ctrl+Alt+L〉键,即可格式化所有代码。