Python编码规范

分号

不要在行尾加分号, 也不要用分号将两条命令放在同一行.

行长度

每行不超过80个字符,例外: 1. 长的导入模块语句 2. 注释里的URL

不要使用反斜杠连接行.
Python会将 圆括号, 中括号和花括号中的行隐式的连接起来 , 你可以利用这个特点. 如果需要, 你可以在表达式外围增加一对额外的圆括号.

1
2
3
4
5
Yes: foo_bar(self, width, height, color='black', design=None, x='foo',
emphasis=None, highlight=0)
if (width == 0 and height == 0 and
color == 'red' and emphasis == 'strong'):

如果一个文本字符串在一行放不下, 可以使用圆括号来实现隐式行连接:

1
2
x = ('This will build a very long long '
'long long long long long long string')

在注释中,如果必要,将长的URL放在一行上.

1
2
Yes: # See details at
# http://www.example.com/us/developer/documentation/api/content/v2.0/csv_file_name_extension_full_specification.html

1
2
3
No: # See details at
# http://www.example.com/us/developer/documentation/api/content/\
# v2.0/csv_file_name_extension_full_specification.html

括号

宁缺毋滥的使用括号

除非是用于实现行连接, 否则不要在返回语句或条件语句中使用括号. 不过在元组两边使用括号是可以的.

1
2
3
4
5
6
7
8
9
10
Yes: if foo:
bar()
while x:
x = bar()
if x and y:
bar()
if not x:
bar()
return foo
for (x, y) in dict.items(): ...

1
2
3
4
5
No: if (x):
bar()
if not(x):
bar()
return (foo)

缩进

用4个空格来缩进代码

绝对不要用tab, 也不要tab和空格混用. 对于行连接的情况, 你应该要么垂直对齐换行的元素, 或者使用4空格的悬挂式缩进(这时第一行不应该有参数):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Yes: # Aligned with opening delimiter
foo = long_function_name(var_one, var_two,
var_three, var_four)
# Aligned with opening delimiter in a dictionary
foo = {
long_dictionary_key: value1 +
value2,
...
}
# 4-space hanging indent; nothing on first line
foo = long_function_name(
var_one, var_two, var_three,
var_four)
# 4-space hanging indent in a dictionary
foo = {
long_dictionary_key:
long_dictionary_value,
...
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
No: # Stuff on first line forbidden
foo = long_function_name(var_one, var_two,
var_three, var_four)
# 2-space hanging indent forbidden
foo = long_function_name(
var_one, var_two, var_three,
var_four)
# No hanging indent in a dictionary
foo = {
long_dictionary_key:
long_dictionary_value,
...
}

空行

顶级定义之间空两行, 方法定义之间空一行

顶级定义之间空两行, 比如函数或者类定义. 方法定义, 类定义与第一个方法之间, 都应该空一行. 函数或方法中, 某些地方要是你觉得合适, 就空一行.

空格

按照标准的排版规范来使用标点两边的空格

括号内不要有空格.

1
Yes: spam(ham[1], {eggs: 2}, [])

1
No: spam( ham[ 1 ], { eggs: 2 }, [ ] )

不要在逗号, 分号, 冒号前面加空格, 但应该在它们后面加(除了在行尾).

1
2
3
Yes: if x == 4:
print x, y
x, y = y, x

1
2
3
No: if x == 4 :
print x , y
x , y = y , x

参数列表, 索引或切片的左括号前不应加空格.

1
Yes: spam(1)

1
no: spam (1)
1
Yes: dict['key'] = list[index]
1
No: dict ['key'] = list [index]

在二元操作符两边都加上一个空格, 比如赋值(=), 比较(==, <, >, !=, <>, <=, >=, in, not in, is, is not), 布尔(and, or, not). 至于算术操作符两边的空格该如何使用, 需要你自己好好判断. 不过两侧务必要保持一致.

1
Yes: x == 1

1
No: x<1

=用于指示关键字参数或默认参数值时, 不要在其两侧使用空格.

1
Yes: def complex(real, imag=0.0): return magic(r=real, i=imag)

1
No: def complex(real, imag = 0.0): return magic(r = real, i = imag)

不要用空格来垂直对齐多行间的标记, 因为这会成为维护的负担(适用于:, #, =等):

1
2
3
4
5
6
7
8
Yes:
foo = 1000 # comment
long_name = 2 # comment that should not be aligned
dictionary = {
"foo": 1,
"long_name": 2,
}

1
2
3
4
5
6
7
8
No:
foo = 1000 # comment
long_name = 2 # comment that should not be aligned
dictionary = {
"foo" : 1,
"long_name": 2,
}

Shebang

在计算机科学中, Shebang (也称为Hashbang)是一个由井号和叹号构成的字符串行(#!), 其出现在文本文件的第一行的前两个字符. 在文件中存在Shebang的情况下, 类Unix操作系统的程序载入器会分析Shebang后的内容, 将这些内容作为解释器指令, 并调用该指令, 并将载有Shebang的文件路径作为该解释器的参数. 例如, 以指令#!/bin/sh开头的文件在执行时会实际调用/bin/sh程序.

  • 文件头部要声明编码类型,默认使用utf8
    1
    # -*- coding:utf-8 -*-

可以使用以上的兼容写法,也可以直接 # coding: utf-8 , 见 Defining Python Source Code Encodings

  • 对于需要执行的 Python 文件,头部可以声明所使用的 Python 解释器的路径,放在编码类型声明之后
    推荐使用 env 的声明方式,这样可以根据运行环境选择当前的 Python:

    1
    #!/usr/bin/env python
  • 如果要使用特定的执行路径的话,也可以直接写:

    1
    #!/usr/bin/python

大部分.py文件不必以#!作为文件的开始. #!先用于帮助内核找到Python解释器, 但是在导入模块时, 将会被忽略. 因此只有被直接执行的文件中才有必要加入#!.

Main

即使是一个打算被用作脚本的文件, 也应该是可导入的. 并且简单的导入不应该导致这个脚本的主功能(main functionality)被执行, 这是一种副作用. 主功能应该放在一个main()函数中.

在Python中, pydoc以及单元测试要求模块必须是可导入的. 你的代码应该在执行主程序前总是检查 if __name__ == '__main__' , 这样当模块被导入时主程序就不会被执行.

1
2
3
4
5
def main():
...
if __name__ == '__main__':
main()

所有的顶级代码在模块导入时都会被执行. 要小心不要去调用函数, 创建对象, 或者执行那些不应该在使用pydoc时执行的操作.

编码建议

  1. 空的str,list,tuple,set,dict0,0.0,None 都是 False. 判断list是否为空时,用if not somelist而不是if len(somelist) == 0.判断list是否非空,则用if somelist而不是if len(somelist) > 0,其他类型同理.
  2. 只是判断是否是None,则用isis not进行判断.使用if a is not None而不是if not a is None.
  3. 使用for item in list:迭代list,使用for index, item in enumerate(list):迭代list并获取数字索引.默认索引初值是0,可指定索引初始值,如:for index, item in enumerate(list, 1):,则索引从1开始计数.
  4. 使用innot in操作判断,str是否有某子串,list,tuple,set是否有某元素,dict是否有某个键.
大师兄 wechat
欢迎关注我的微信公众号:Python大师兄