python风格规范
1.分号
不要在行尾添加分号,也不要用分号将两条命令放在同一行
2.行长度
每行不超过80个字符
例外:
(1)长的导入模块语句
(2)注释里的URL
不要使用反斜杠连接行。
python会将圆括号,中括号和花括号中的行隐式的连接起来,可以利用这个特点,如果需要,可以在表达式外围增加一对额外的圆括号。
比如:
foo_bar(self, width, height, color= ='black', design= =None, x= ='foo', emphasis= =None, highlight= =0) if if (width == == 0 and and height == == 0 and and color == == 'red' and and emphasis == == 'strong'):
如果一个文本字符串在一行放不下,可以使用圆括号来实现隐式行连接:
x =('This will build a very long long ' 'long long long long long long string')
3.括号
宁缺毋滥的使用括号。除非是用于实现行连接,否则不要在返回语句或条件语句中使用括号。不过在元组两边使用括号是可以的。
比如:
Yes: if foo: bar() while x: x = bar() if x and and y: bar() if not not x: bar() return foo for (x, y) in in dict. .items(): ... ... No: if (x): bar() if not not(x): bar() return (foo)
4.缩进
用4个空格来缩进代码。绝对不要用tab,也不要tab和空格混用。对于行连接的情况,要么垂直对齐换行的元素,或者使用4空格的悬挂式缩进(这时第一行中不要有参数):
即如果圆括号或者中括号中有多个参数,第一个参数和左半边括号位于同一行,则换行之后的参数和第一个参数对齐即可;如果第一个参数没有和左半边括号同一行,而是另起一行,则另起一行的参数前放4个空格即可。
# 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, ... }
5.空行
顶级定义之间空两行,方法定义之间空一行
顶级定义,比如函数或者类定义,之间空两行;方法定义,类定义和第一个方法之间,空一行。函数或方法中,某些地方觉得合适,空一行
6.空格
按照标准的排版规范来使用标点两边的空格。
括号内紧贴括号两边不要有空格,比如: spam(ham[1], {eggs:2}, [])
不要在逗号,分号,冒号前面加空格,但应该在他们后面加(除了在行尾)。
应该: if x == 4: print x, y x, y = y, x 不应该: if x == 4 : print x , y x , y = y , x
参数列表,索引或切片的左括号前不应加空格
应该: spam(1) dict['key'] = list[index] 不应该: spam (1) dict ['key'] = list [index]
在二元操作符两边都加上 一个空格,比如赋值(=),比较(==, <, >, != ,<>, <=, >=, in, not in, is, is not)布尔(and, or, not)。至于算术操作符两边的空格该如何使用,需要自己好好判断,不过两侧务必要保持一致。
应该: x == 1 不应该: x<1
当'='用于指示关键字参数或者默认参数时,不要在其两侧使用空格:
应该: def complex(real, imag=0.0): return magic(r=real, i=imag) 不应该: def complex(real, imag = 0.0): return magic(r = real, i = imag)
不要使用空格来垂直对齐多行间的标记,这会称为维护的负担(适用于 :, #, =等)
应该 foo = 1000 # comment long_name = 2 # comment that should not be aligned dictionary = { "foo": 1, "long_name": 2, } 没有必要将注释 #之后的内容对齐
7.注释
确保对模块、函数、方法和行内注释使用正确的风格
(1)文档字符串
python中独一无二的注释方式,文档字符串。文档字符串是包、模块、类或函数里的第一个语句。这些字符串可以通过对象的doc成员被自动提取,并且被pydoc所用。
文档字符串使用三个双引号,一个文档字符串应该这样组织:首先是一行以句号,问号或惊叹号结尾的概述(或者该文档字符串单纯只有一行);接着是一个空行,接着是文档字符串剩下的部分,它应该与文档字符串中的第一行的第一个引号对齐。
(2)函数文档字符串
一个函数必须要有文档字符串,除非它满足以下条件:
(a)外部不可见
(b)非常短小
(c)简单明了
文
档字符串应该包含函数做什么,以及输入和输出的详细描述。通常不应该描述“怎么做”,除非是一些复杂的算法。文档字符串应该提供足够的信息,当别人编写代
码调用该函数的时候,它不需要看一行代码,只要看文档字符串就够了。对于复杂的代码,在代码旁边加注释会比文档字符串更有意义。
函数的文档字符串格式,将函数按照参数、返回值、抛出异常等信息分小节进行描述,每小节应该以一个标题行开始,标题行以冒号结尾,出标题行外。解的而其他内容应被缩进2个空格
Args: 列出每个参数的名字,并在名字后使用冒号和一个空格,分割对该参数的描述。如果描述太长超过了单行80个字符,使用2或者4个空格的悬挂缩进(与文件其他部分保持一致) 描述应该包含所需的类型和含义,如果一个函数接受 *foo (可变长度参数列表)或者 **bar(任意关键字参数),应该详细列出*foo和**bar Returns:(或者Yields,用于生成器) 描述返回值的类型和语义。如果函数返回none,这一部分可以忽略 Raises: 列出与接口有关的所有异常 ``` ``` def fetch_bigtable_rows fetch_bigtable_rows(big_table, keys, other_silly_variable= =None): """Fetches rows from a Bigtable. Retrieves rows pertaining to the given keys from the Table instance represented by big_table. Silly things may happen if other_silly_variable is not None. Args: big_table: An open Bigtable Table instance. keys: A sequence of strings representing the key of each table row to fetch. other_silly_variable: Another optional variable, that has a much longer name than the other args, and which does nothing. Returns: A dict mapping keys to the corresponding table row data fetched. Each row is represented as a tuple of strings. For example: {'Serak': ('Rigel VII', 'Preparer'), 'Zim': ('Irk', 'Invader'), 'Lrrr': ('Omicron Persei 8', 'Emperor')} If a key from the keys argument is missing from the dictionary, then that row was not found in the table. Raises: IOError: An error occurred accessing the bigtable.Table object. """ pass
(3)类文档字符串
类应该在其定义下有一个用于描述该类的文档字符串,如果你的类有公共属性(Attributes),那么文档中应该有一个属性(Attributes)段,并且应该遵守和函数参数相同的格式。
class SampleClass(object): """Summary of class here. Longer class information.... Longer class information.... Attributes: likes_spam: A boolean indicating if we like SPAM or not. eggs: An integer count of the eggs we have laid. """ def __init__(self, likes_spam=False): """Inits SampleClass with blah.""" self.likes_spam = likes_spam self.eggs = 0 def public_method(self): """Performs operation blah."""
(4)块注释和行注释
最需要注释的是代码中那些技巧性的部分。对于复杂的操作,应该在操作开始前写上若干行注释,对于不是一目了然的代码,应该在其行尾添加注释。
# comments..... # ..... # .... if i & (i-1) == 0: xxx
为了提高可读性,注释应该至少离开代码两个空格。
8.类
如
果一个类不继承自其它类,就显示的从object继承,嵌套类也是一样。继承自object是为了使属性正常工作,并且这样可以保护你的代码,使其不受
python 3000的一个特殊的潜在不兼容性影响,这样做也定义了一些特殊的方法,这些方法实现了对象的默认语义,包括:__new__,
__init__, __delattr__, __getattribute__, __setattr__, __hash__,
__repr__, __str__.
9.字符串
即使参数都是字符串,也尽量使用%操作符或者格式化方法来格式化字符串。
应该: x = a + b x = '%s, %s!' % (imperative, expletive) x = '{}, {}!'.format(imperative, expletive) x = 'name: %s; score: %d' % (name, n) x = 'name: {}; score: {}'.format(name, n) 不应该: x = '%s%s' % (a, b) x = '{}{}'.format(a, b) x = imperative + ', ' + expletive + '!' x = 'name: ' + name + '; score: ' + str(n)
注意避免在循环中使用+ 和+= 操作符来累加字符串,由于字符串是不可变的,这样做会创建不必要的临时对象,并且导致二次方而不是线性的运行时间。作为替代方案,可以将每个子串加入列 表,然后在循环结束后用 .join 连接列表(也可以将每个子串写入一个 cStringIO.StringIO缓存中)
应该: items = ['<table>'] for last_name, first_name in employee_list: items.append('<tr><td>%s, %s</td></tr>' % (last_name, first_name)) items.append('</table>') employee_table = ''.join(items) 不应该: employee_table = '<table>' for last_name, first_name in employee_list: employee_table += '<tr><td>%s, %s</td></tr>' % (last_name, first_name) employee_table += '</table>'
为多行字符串使用三重双引号,而非三重单引号。当且仅当项目中使用单引号来引用字符串时,才可能会使用三重单引号为非文档字符串的多行字符串来标识引用。文档字符串必须使用三重双引号。
不过,需要注意,通常用隐式行连接更清晰,因为多行字符串与程序其他部分的缩进方式不一致。
应该: print(" this is much nicer.\n" "do it this way.\n") 不应该: print """this is pretty ugly. don't do this. """
9.文件和socket
推荐使用"with 语句"管理文件:
with open("hello.txt") as hello_file: for line in hello_file: print line
对于不支持with语句的类似文件对象,可以使用contextlib.closing()
import contextlib with contextlib.closing(urllib.urlopen("http://www.python.org/")) as front_page: for line in front_page: print line
10. 导入格式
每个导入应该独占一行,导入总应该放在文件顶部,位于模块注释和文档字符串之后,模块全局变量和常量之前。导入应该按照从最通用到最不通用的顺序分组:
(1)标准库导入
(2)第三方库导入
(3)应用程序指定导入
每种分组中,应该根据每个模块的完整包路径按照字典序排序,忽略大小写。
import foo from foo import bar from foo.bar import baz from foo.bar import Quux from Foob import ar
11. 语句
通常每个语句应该独占一行。如果测试结果和测试语句在一行放得下,可以将他们放在同一行。如果是if语句,只有在没有else时才能这样做。特别的,绝对不要对 try/except这样做,因为try和except不能放在同一行。 if foo: bar(foo)
12. 访问控制
在python中,对于琐碎又不太重要的访问函数应该直接使用公有变量来取代他们,这样可以避免额外的调用开销。当添加更多功能时,你可以用属性(property)来保持语法的一致性。
13. 命名
module_name,
package_name, ClassName, method_name, ExceptionName, function_name,
GLOBAL_VAR_NAME, instance_var_name, function_parameter_name,
local_var_name.
应该避免的名称:
(1)单字符的名称,除了计数器和迭代器
(2)包/模块名中的连字符
(3)双下划线开头并结尾的名称(python保留,比如init)
命名约定:
(1)所谓“内部”表示仅模块内可用,或者在类内是保护或者私有的
(2)用单下划线_ 开头表示模块变量或函数使protected的(使用import * from xx时不会包含进来)
(3)用双下划线__开头的示例变量或方法表示类内私有
(4)将相关的类和顶级函数放在同一个模块里。不像java,每必要限制一个类一个模块
(5)对类名使用大写字母开头的单词(如CapWords,即Pascal风格),但是模块名应该用小写加下划线的方式(如 lower_with_under.py)
14. main
即使是一个打算被用作脚本的文件,也应该是可导入的。并且简单的不应该导致这个脚本的主功能被执行,这是一种副作用。主功能应该放在一个main函数中、
在python中,pydoc以及单元测试要求模块必须是可导入的,你的代码应该在执行主程序前总是检查 ifname == 'main', 这样当模块被导入时主程序不会被执行。
所有的顶级代码在模块导入时都会被执行,要小心不要去调用函数,创建对象,或者执行那些不应该在使用pydoc时执行的操作。