Python代码书写规范
最近在编写一些Python程序,之前没有专门了解过代码的书写规范,这里对一些规范做一些整理,更加符合行业规范,同时利于自己和他人的阅读。
要点总结
- 要个要求4个空格缩进,而不是制表符
- 注意代码长度,每行不超过79个字符,并适当使用换行符
- 注意适当的代码空行以更好地区分代码区域
- 代码注释和文档注释说明必须正确,并优先更新
- 源代码编码格式统一使用utf-8,或和旧文件代码保持一致
- 从文件到类与函数甚至是变量的命名都要保持规范,且不要使用中文
- 重要的是要意识到代码的阅读比编写的频率要高很多
空格
- 运算符两侧和函数参数之间建议使用空格进行分割
- 括号内两侧不要有空格
- 不要在逗号、分号、冒号前面有空格,但应该在它们后面加(除了在行尾)
- 当=用于指示关键字参数或默认参数值时,不要在其两侧使用空格
- 避免使用不必要的空格,不要为了对齐增加空格
空行
- 顶层函数和类的定义,前后用两个空行隔开
- 类里的方法定义用一个空行隔开
- 相关的功能组可以用额外的空行隔开(谨慎使用)
- 一堆相同的单行代码之间的空白行可以省略
- 在函数中使用空行来区分逻辑段(谨慎使用)
注释
- 总体原则:错误的注释不如没有注释,当一段代码发生变化时,第一件事就是修改注释
- 注释必须使用英文,最好是完整的句子,首字母大写,句后就有结束符,结束符后跟两个空格,开始下一句。如果是短语,可以省略结束符
- 块注释:在一段代码前增加的注释,在#后加一空格,段落之间以只有#的行间距
- 行注狮:在一句代码后加注释,应离开代码2个空格,但是这种方式尽量少使用
- 避免无谓的注释
- 没有必要用空格来垂直对齐多行间的标记,这会造成维护的负担
- 文档字符串:要为所有的公共模块、函数、类以及方法编写文档说明。非公共的方法没有必要,但是应该有一个描述方法具体作用的注释。这个注释应该在def那一行之后。对于单行的文档说明,尾部的三引号应该和文档在同一行。特别需要注意的是,多行文档说明使用的结尾三引号应该自成一行。
循环
- 应该避免在循环中使用+和+=操作符累加字符串,这是因为字符串时不可变的,这样会创建不必要的临时对象,推荐做法是将每个字符串加入列表,然后循环结束后使用join()方法连接列表
长语句
- 除了长的import语句和注释里的URL,每行尽量不超过80个字符,并且尽量避免使用反斜杠连接行
- 可以在表达式外围增加一对额外的圆括号用来连接不同行,这是因为Python会将圆括号、中括号和花括号中的行隐式地连接起来
- 在注释中,如果必要,将长的URL放在一行上
导入模块
- 用import或者from…import来导入相应的模块
- 尽量不要使用通配符导入的模式(from somemodule import *),因为命名空间的变量可能会引起冲突
from somemodule import *
import somemodule as sm
from somemodule import (func1, func2, func3, func4, func5)
- 模块导入总是位于文件的顶部,在模块注释和文档字符串之后,在模块的全局变量与常量之前
- 模块导入按照以下顺序分组:标准库导入,相关第三方库导入,本地应用/库特定导入;并且在每一组导入之间加入空行
- 推荐使用绝对路径导入
- 当从一个包含类的模块中导入类时,需要考虑是否会导致名字的冲突
from myclass import MyClass
from foo.bar.yourclass import YourClass
import myclass
import foo.bar.yourclass
myclass.MyClass
foo.bar.yourclass.YourClass
- 每个import语句只导入一个模块,尽量避免依次导入多个模块
保留字
- 保留字即关键字,不能作为任何标识符的名称
- Python的标准库提供了一个keyword模块,可以输出当前版本的所有关键字
import keyword
print(keyword.kwlist)
命名规范
- 函数命名尽量短小并且使用小写字母,如果想提高可读性可以用下划线分割
- 类名采用单词首字母大写的驼峰式命名方法,例如GetMoney,History等
- 使用单下划线开头的模块变量或者函数是受保护的,在使用import * from语句从模块中导入时这些变量或者函数不能被导入
- 使用双下划线开头的变量或方法是私有的
- 不要使用字母l、O、I作为单字符变量名,易混淆
缩进
- 每级缩进使用4个空格,在冒号换行后一定要跟一个缩进,不然会出现语法错误
- 连续行应该对齐折叠元素,无论是垂直的隐式行连接,还是使用悬挂缩进(第一行没有参数并且使用更多的缩进来区别它本身和连续行)
foo = long_function_time(var_one, var_two,
var_three. var_four)
def long_function_name(
var_one, var,two, var_three,
var_four):
print(var_one)
foo = long_function_name(
var_one, var_two, var_three,
var_four)
- 当if语句的条件部分长到需要换行写的时候,注意可以在两个字符关键字的连接处(比如if),增加一个空格,再增加一个左括号来创造一个4空格缩进的多行条件。但这会与if语句内同样使用4空格缩进的代码产生视觉冲突。对于如何在视觉上进一步将这些条件行与if语句内的嵌套套件区分开,可使用的选项包括但不限于以下几种情况:
if (this_is_one_thing and
that_is_another_thing):
do_something()
if (this_is_one_thing and
that_is_another_thing):
do_something()
if (this_is_one_thing and
that_is_another_thing):
do_something()
- 在多行结构中的大括号/中括号/小括号的右括号可以与内容对齐单独起一行作为最后一行的第一个字符
my_list = [
1, 2, 3,
4, 5, 6,
]
my_list = [
1, 2, 3,
4, 5, 6,
]
- 在二元运算符之前换行,遵循数学的传统,使得运算符和操作数很容易进行匹配
income = (gross_wages
+ taxable_interest
+ (dividends - qualified_dividends)
- ira_deduction
- student_loan_interest)