PEP 8 程序代码的编写风格指南
PEP 8 程序代码的编写风格指南
参考
PEP 8 -- Style Guide for Python Code
介绍
PEP ( Python Enhancement Proposals ) - Python 语言精进建议书
本份文件提供Python代码编写的守则, 有关为Python 语言以C语编写的部份请参考PEP 7.
如果某些项目具有特定的编写风格, 以该项目为主.
这个愚笨的代码编写一致性要求是来自于淘气鬼的一点小心思.
编者意见:
这守则太过繁杂, 想遵守的人看了都会疯了. 重点如果简单, 很多人自然会遵循去作. 要不是受到Python相关人员的提示要求, 我肯定不会去管PEP 8的要求, 顶多就是三件事: 每行不超过80个字, 排版对齐, 加上一些说明.
本文非直接翻译的结果, 如果有错误, 敬请提示.
代码被读的机会比编写的机会多, 这里的守则, 目的在于改善代码的可读性及各类不同应用的一致性.
不要只为了符合本守则, 而破坏了有关旧版的兼容性.
可以忽视本守则的原因:
- 当应用本守则时, 会造成可读性降低.
- 为了与周遭的代码一致, 可能是因为旧代码的存在.
- 在本守则建立以前的旧代码.
- 为了兼容与不支持本守则的旧版Python.
代码的布局
缩格
每一层级的缩格使用4个空格符, 不要使用Tab, 除非要兼容原已使用Tab缩格的代码.
使用大中小括号来分行时应该要作到垂直对齐, 其中段落中除第一行外, 其他各行都应该要缩格. 左括号是第一行的最后一个非空白字符, 并且没有任何的参数; 如果第一行的内容太短, 比如 if ( 就没有必要这么作. 右括号可以放在最后一行的第一个字.
如果分行的缩格无法与下一语句的缩格区分, 必须在分行前再加一级缩格.
每一行的最大长度
限制每一行的最大长度为79个字母. 文件说明或批注最大长度为72个字母. 尽可能使用括号来分行, 而不要使用倒斜线, 除非前者无法使用.
二元运算符 (+, - ,* ,/ , ... )
运算符前分行会更有可读性
空行的使用
- 顶层函数及类的定义应该前后加两个空行.
- 类中的方法则前后加一个空行.
- 相关功能的语句可以保守地使用空行与别的语句区隔.
- 单行语句的空行可以省略.
- 函数中逻辑的部份可以保守地使用空行.
源代码的编码方式
- 永远都使用 UTF-8 (在 Python 2 中使用的是 ASCII)
- 使用 UTF-8 或 ASCII 不应该有编码的宣称.
- 标准库中, 非省缺的编码只能用在测试时或文件说明及批注中, 否则使用 \x, \u, \U 或 \N 脱离字符来包含非ASCII的资料.
- 标准库中, 所有的标示符必须使用ASCII, 也应该是英文字母. 字符串及批注也必须是ASCII. 作者名是一个例外, 但必须转译为拉丁字母表 ( latin-1 )
Import
- import 语句应该放在模块批注及文件说明之后, 模块全局变量及常数之前.
- import 应该分为三群, 标准库, 第三方库, 自己的库; 用空行来分隔
- 建议使用絶对路径 import; 标准库应该使用絶对路径 import. 不要使用隐式相对路径的 import, Python 3 已经移除这种方式.
- 不要使用 import *, 会造成命名的混淆或重复.
- 不同模块不要写在同一个 import 语句中, 同一个模块可以写在一个import 语句中.
模块级的双底线变量名
- 除了 from __future__ import 以外, 所有双线的变量名宣称应该放在文件说明之后, 其他 import 之前. Python 指定 from __future__ import 必须放在文件说明之后, 以及其他代码之前.
字符串引号
- 字符串的引号使用单引号或双引号都是可以的.
- 文件说明则要使用三个双引号.
表达式与语句中的空格
- 避免额外多余的空格
- 括号前不要有空格.
- 逗号前不要有空格.
- 冒号前后空格数量要一样.
- 函数名, 类名及变量名后要紧接括号.
- 不要为了对齐某个字而增加空格, 比如等号.
其他建议
- 每一行的后面不要有空格.
- 运算符前后都加上一个空格.
- 不同运算顺序的运算符, 可以考虑在运算顺序较后的运算符前后各加一个空格.
- 非 -> 的关键词及缺省值所使用的等号前后不要有空格. -> 时则要加空格.
- -> 前后各加一个空格.
- 不要使用超过一个的空格.
- 不建议使用组合单行的语句
逗号在后
- 只有一个元素的Tuple使用, 必须在括号内使用.
批注
- 代码更新时, 也请更新批注.
- 批注要是一个完整的句子; 第一个字除非是变量名, 否则应该要大写; 每个句子结束要有句点; 两个句子之间应该要有两个空格.
- 英文书写请依循 "Strunk and White" ( 英文写作指南 ).
- 除非很确定代码不会被其他语言国家的人来读, 否则请以英文来书写.
- 区块批注中的段落使用一个 # 的空行来分隔.
- 行批注少用, 使用时, 至少空两个空格, # 后加一个空格, 语意明显的就不用说明
文件说明字符串
- 守则请看PEP 257.
- 对所有的公开模块, 函数, 类以及方法, 要写文件说明字符串.
- 非公开的部份, 应该要有批注说明其用意, 批注放在 def 下一行.
- """ 要单独放在文件说明字符串的最后一行, 除非只有一行.
名字定义方式
- 名字定义的方式所要反应的是用法, 而不创建.
- 前置字在模块用来群组化是没有意义的, 因为模块带头已经说明了一切.
- 前有一底线的, 为弱内部使用, 在 import * 中, 不会被引入.
- 后有一底线的, 用来避免与Python的闗键字混淆.
- 前有双底线的, 会造成与类名连接, 引起混淆.
- 前后有双底线的只在用户所有的名空间内.
命名守则
- 不要用小写的 L, 大写的 O, 大写的 I, 来作为单字母的变量名.
- 使用 ASCII 变量名.
- 模块/库 - 短的全小写字母 (+中间底线, 不建议使用), C/C++模块前面要加一个底线.
- 类 - 大写字母开头的字组
- 内建 - 单一或两个字的组合, 大写字母开头的字组只适用在exception名, 以及常数.
- 变量名定义在 PEP 484, 为优先使用大写字母开头的字组, 后面加底线再加小写的字, 以代表相应的变量.
- 异常名字 - 同类的方式, 后面应加上底线及Error.
- 全局变量 - 在单一模块内使用, 如函数名一样, 旧守则是在前面加上一个底线.
- 函数及变量名 - 全小写字母, 或可加上居中底线, 混合方式只限定已有的样式, 以达到兼容要求.
- 函数与方法的参数 - 类的方法使用 cls 作为第一个参数, 实例方法使用 self 作为第一个参数. 如果函数的参数与关键词冲突, 最好是加一个后底线, 或使用同意字, 而不是改名字.
- 方法与实例 - 小写字母, 或可加上居中底线, 如果是私有的方法或实例, 加一个前底线.
- 避免与子类冲突, 加前双底线, 将无法被外部直接取用, 但可间接取用(模块名._模块名+变量名)
- 常数 - 全大写+中底线
- 公开的部份, 修改可能要考虑兼容的问题; 公开的部份则不需要. 没有文件说明的接口都被视为非公开的.
- 公开的属性没有前底线, 与关键词冲突则加后底线.
编程建议
- 代码的编写不会破坏其他的代码. 比如字符串的相加, 不要用 + 号, 最好是使用 ''.join()
- 单态类的比较, 使用 is 或 is not, 而不要用 == 或 !=; 逻辑类的if result, 最好是 if result is not None. 使用 is not, 而不是 not is.
- 顺序的比较最好是使用 (__eq__, __ne__, __lt__, __le__, __gt__, __ge__), 可以用在不同的种类比较上. 可以参考 functools.total_ordering(), PEP 207.
- 使用 def 好过使用 lambda
- 从 Exception 找异常, 而不是从 BaseException 去找. PEP 3151
- Exception 发生时, 应该把相关的细节都回传到新的 Exception.
- 指明发生的异常, 而不是只有 except:.
- try中的语句越少越好.
- 当来源只适用某些语句时, 使用 with 方法/函数.
- 所有的情况都应明白指出返回的结果.
- 使用字符串方法, 而不是使用字符串模块.
- 使用 ''.startswith() 与 ''.endswith() 代替检查字符串的前后文.
- 使用 isinstance() 来检查类型, 而不是type().
- 空的string, list 与 tuple代表的是False.
- 字符串中后面的空格可能会被删除.
- 不要用 == 或 is 来比较 逻辑值.
- 不要在 try ... finally 中使用 return/break/continue.
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: