python编程规范---学习记录3.10(持续更新)
0. 前言
Python编程规范官方文档:PEP8 - style guide for Python code
代码规范、风格统一,能够提高代码的可读性并且便于发现问题。编程规范是项目开发中非常重要的习惯。
1. 代码编写
1.1 缩进
Python能够使用缩进来表示代码块,无需使用{}。但是同一个代码块下的语句,其缩进的空格数必须是相等的,例如
if True:
print ("Answer")
print ("True")
else:
print ("Answer")
print ("False") # 缩进不一致,会导致运行错误
一般是一行写完一条语句,如果语句很长可以使用反斜杠\来实现多行语句,例如:
total = item_one + \
item_two + \
item_three
在 [], {}, () 中的多行语句,不需要使用反斜杠\,例如:
total = ['item_one', 'item_two', 'item_three',
'item_four', 'item_five']
在多行结构当中, {}, [], () 中的右括号可以与内容对齐单独一行作为最后一行,也能够与多行结构中第一行的第一个字符对齐作为最后一行,例如:
my_list = [
1, 2, 3,
4, 5, 6,
]
my_list = [
1, 2, 3,
4, 5, 6,
]
1.2 行的最大长度
所有行限制的最大字符数为79。
不要使用反斜杠\后回车进行续行操作,可以使用 {}, [], () 隐式连接,例如:
# yes
x = ('1234567896+16523234654162164+5 '
'555555555555555555555......555555555555555555555')
# no
x = ('1234567896+16523234654162164+5 '\
'555555555555555555555......555555555555555555555')
1.3 二元运算符之前是否换行
为了不影响代码的可读性,推荐在二元运算符之前中断,例如:
# 运算符和操作数很容易进行匹配
income = (gross_wages
+ taxable_interest
+ (dividends - qualified_dividends)
- ira_deduction
- student_loan_interest)
1.4 空行
类和top-level函数定义之间空两行;类中的方法定义之间空一行;函数内逻辑无关段落之间空一行;其他地方尽量不要再空行。
1.5 导入
不要在一句import中同时导入多个库,例如:
# yes
import os
import sys
# no
import sys, os
但是可以这样同时导入多个库,例如:
from subprocess import Popen, PIPE
当从一个包含类的模块中导入类时,常常这么写:
from myclass import MyClass
from foo.bar.yourclass import YourClass
如果上述的写法导致名字的冲突,那么这么写:
import myclass
import foo.bar.yourclass
然后使用 “myclass.MyClass” 和 “foo.bar.yourclass.YourClass” 调用。
2. 字符串的引号
2.1 字符串的引号
在Python中,使用单引号和双引号的字符串是相同的。但是对文档字符串的注释,通常使用三引号。当字符串的内容包含单引号或者双引号的时候,可以使用与字符串内部不同的引号来避免使用反斜杠,例如:
# 字符串中有单引号时,外层可使用双引号,反之亦然
a = "let's go !"
b = 'I like "python"!'
# 字符串中有单引号时,也可以使用\增加可读性,但这种方法不太推荐
c = 'let\'s go !'
# 字符串中可以使用\n换行
d = 'hello,\nworld!'
3. 语句中的空格
3.1 避免不必要的空格
括号内不要无故空格,例如:
# yes
spam(ham[1], {eggs: 2})
# no
spam( ham[ 1 ], { eggs: 2 } )
逗号、分号或者冒号之前,不要空格,例如:
# yes
if x == 4: print x, y; x, y = y, x
# no
if x == 4 : print x , y ; x , y = y , x
二元运算符的左右两边应该各有一个空格。在使用冒号切片的时候,所有的冒号需间距相同,但是当一边的切片参数被省略时,空格也被省略。例如:
# yes
ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:]
ham[lower:upper], ham[lower:upper:], ham[lower::step]
ham[lower+offset : upper+offset]
ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
ham[lower + offset : upper + offset]
# no
ham[lower + offset:upper + offset]
ham[1: 9], ham[1 :9], ham[1:9 :3]
ham[lower : : upper]
ham[ : upper]
在调用函数或者索引时,左括号前不要空格,例如:
# 函数
# yes
spam(1)
# no
spam (1)
# 索引
# yes
dct['key'] = lst[index]
# no
dct ['key'] = lst [index]
也不需要为了对齐语句而添加空格,例如:
# yes
x = 1
y = 2
long_variable = 3
# no
x = 1
y = 2
long_variable = 3
3.2 其它
避免在语句的尾部添加空格,容易混乱。
使用不同优先级的运算符,需在最低优先级的运算符周围添加空格,但是不要使用一个以上的空格。例如:
# yes
i = i + 1
submitted += 1
x = x*2 - 1
hypot2 = x*x + y*y
c = (a+b) * (a-b)
# no
i=i+1
submitted +=1
x = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)
在函数中指定参数时,不用在=左右加上空格,例如:
# yes
def complex(real, imag=0.0):
return magic(r=real, i=imag)
# no
def complex(real, imag = 0.0):
return magic(r = real, i = imag)
但是在给有类型备注的参数赋值时,需要在=左右添加空格,例如:
# yes
def munge(sep: AnyStr = None): ...
def munge(input: AnyStr, sep: AnyStr = None, limit=1000): ...
# no
def munge(input: AnyStr=None): ...
def munge(input: AnyStr, limit = 1000): ...
不要在同一行中写多个语句,用;隔开也不可以,例如:
# yes
if foo == 'blah':
do_blah_thing()
do_one()
do_two()
do_three()
# no
if foo == 'blah': do_blah_thing()
do_one(); do_two(); do_three()
if/for/while语句中,即使执行语句只有一句,也必须另起一行,不能放在一起,例如:
# no
if foo == 'blah': do_blah_thing()
for x in lst: total += x
while t < 10: t = delay()
# no
if foo == 'blah': do_blah_thing()
else: do_non_blah_thing()
try: something()
finally: cleanup()
do_one(); do_two(); do_three(long, argument,
list, like, this)
if foo == 'blah': one(); two(); three()
4. 注释
4.1 代码块注释
在一段代码前增加注释的时候,要在#后加一个空格。
在段落之间进行注释的时候,要用只有一个#的空行来分隔。
4.2 行内注释
行内注释时,注释与代码至少要两个空格分隔,并且注释要以#和一个空格开始。尽量不要使用不必要的行内注释。
4.3 文档注释
文档注释在PEP 257中有介绍:PEP 257。
需要对公共的模块、函数和类以及方法编写文档说明。注释需在def这一行之后编写。
5. 命名规范
5.1 命名注意事项
- 尽量不要使用小写字母‘l’,大写字母‘O’、‘I’ 等容易混淆的字母,作为变量名。
- 模块命名尽量短小,使用全部小写的方式,可以使用下划线。
- python包命名尽量短小,使用全部小写的方式,不可以使用下划线。
- 类的命名使用首字母大写(CapWords)的方式。
- 异常命名使用CapWords+Error后缀的方式。
- 全局变量名只在模块内部使用时,命名方法和函数命名规则一样小写,也可用下划线分隔。
- 函数名应该小写,如果想提高可读性可以用下划线分隔。
- 常量命名应该大写,可以使用下划线分隔。
- 始终要将 self 作为实例方法的的第一个参数。始终要将 cls 作为类静态方法的第一个参数。若函数的参数名和已有关键词冲突,则在参数后加一个下划线即可。
- 为避免类中的属性名与子类属性名冲突,则可前缀双下划线。
6. 编码建议
- 代码编写不应降低其它代码的实现效率。
- 尽可能使用 ‘is’、‘is not’ 取代 ‘==’,使用 ‘is not’ 运算符而不是 ‘not is’ ,例如:
# yes
if foo is not None:
# no
if not foo is None:
- 当使用富比较(rich comparisons,一种复杂的对象间比较的新机制,允许返回值不为-1,0,1)实现排序操作的时候,最好实现全部的六个操作符(eq, ne, lt, gt, ge)而不是依靠其他的代码去实现特定的比较。
- 从Exception继承异常,而不是BaseException。直接继承BaseException的异常适用于几乎不用来捕捉的异常。
- 字符串不能以空格作为结尾。