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时执行的操作。

posted @ 2015-12-06 22:22  农民伯伯-Coding  阅读(353)  评论(0)    收藏  举报