编程风格
13 编程风格
13.1 简介
为了编程的规范,我们一般约定一些编程规则、约定,这些都称为编程风格。
13.2 分号
不要在行尾加分号, 也不要用分号将两条命令放在同一行。
13.3 行长度
1) 每行不超过80个字符。当然也有例外的情况,比如:
长的导入模块语句或者注释里的URL
2) 不要使用反斜杠连接行.
Python会将 圆括号,中括号和花括号中的行隐式的连接起来 , 你可以利用这个特点. 如果需要, 你可以在表达式外围增加一对额外的圆括号.
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'):
3) 如果一个文本字符串在一行放不下, 可以使用圆括号来实现隐式行连接:
x = ('This will build a very long long '
'long longlong long long long string')
4) 在注释中,如果必要,将长的URL放在一行上。
#http://www.example.com/us/developer/documentation/api/content/v2.0/csv_file_name_extension_full_specification.html
13.4 括号
除非是用于实现行连接, 否则不要在返回语句或条件语句中使用括号. 不过在元组两边使用括号是可以的。
推荐的代码风格:
if foo:
bar()
while x:
x =bar()
if x and y:
bar()
if not x:
bar()
return foo
for (x, y)in dict.items(): ...
不建议的代码风格:
if (x):
bar()
if not(x):
bar()
return (foo)
13.5 应用
用4个空格来或则tab来缩进代码绝不能tab和空格混用。
13.6 空格
按照标准的排版规范来使用标点两边的空格。
1) 括号内不要有空格.
推荐方式:
spam(ham[1], {eggs: 2}, [])
不建议方式:
spam( ham[ 1 ], { eggs: 2 }, [ ] )
2) 不要在逗号, 分号, 冒号前面加空格, 但应该在它们后面加(除了在行尾).
推荐方式:
if x == 4:
printx, y
x, y = y, x
不建议方式:
if x == 4 :
print x, y
x , y = y ,x
3) 参数列表, 索引或切片的左括号前不应加空格.
推荐方式:
spam(1)
不推荐:
spam (1)
推荐方式:
dict['key'] = list[index]
不推荐方式:
dict ['key'] = list [index]
4) 在二元操作符两边都加上一个空格, 比如赋值(=), 比较(==,<, >, !=, <>, <=, >=, in, not in, is, is not), 布尔(and, or, not). 至于算术操作符两边的空格该如何使用, 需要你自己好好判断. 不过两侧务必要保持一致.
建议方式:
x == 1
不建议:
x<1
5) 当'= '用于指示关键字参数或默认参数值时, 不要在其两侧使用空格.
推荐方式:
def complex(real, imag=0.0): return magic(r=real,i=imag)
不建议方式:
def complex(real, imag = 0.0): return magic(r = real,i = imag)
6) 不要用空格来垂直对齐多行间的标记, 因为这会成为维护的负担(适用于:,#, =等):
推荐方式:
foo =1000 # comment
long_name =2 # comment that should not be aligned
dictionary= {
"foo": 1,
"long_name": 2,
}
不建议方式:
foo = 1000 # comment
long_name =2 # comment that should not bealigned
dictionary= {
"foo" : 1,
"long_name": 2,
}
13.7 注释
1) 文档字符串
一般使用'''或则 """来实现文档字符串。 文档字符串是我们使用Python过程中一个很重要的工具,他对程序文档很有帮助,使程序很容易理解。甚至当程序运行的时候,我们可以从一个函数中返回文档字符串。
2) 函数和方法
下文所指的函数,包括函数, 方法, 以及生成器。一个函数必须要有文档字符串, 除非它外部不可见或者非常短小或者简单明了。
一般我们在函数或者方法里按照Args(参数)、Returns(返回)、Raises(异常抛出)3个方面声明文档字符串。详细解释见下:
Args:
列出每个参数的名字, 并在名字后使用一个冒号和一个空格, 分隔对该参数的描述.如果描述太长超过了单行80字符,使用2或者4个空格的悬挂缩进(与文件其他部分保持一致). 描述应该包括所需的类型和含义. 如果一个函数接受*foo(可变长度参数列表)或者**bar(任意关键字参数), 应该详细列出*foo和**bar.
Returns: (或者 Yields: 用于生成器)
描述返回值的类型和语义. 如果函数返回None, 这一部分可以省略.
Raises:
列出与接口有关的所有异常.
注释代码样例:
"""
def fetch_bigtable_rows(big_table, keys,other_silly_variable=None):
Fetches rowsfrom a Bigtable.
Retrievesrows pertaining to the given keys from the Table instance
representedby big_table. Silly things may happen if
other_silly_variable is not None.
Args:
big_table:An open Bigtable Table instance.
keys: Asequence of strings representing the key of each table row
tofetch.
other_silly_variable: Another optional variable, that has a much
longer name than the other args, and which does nothing.
Returns:
A dictmapping 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 keyfrom the keys argument is missing from the dictionary,
thenthat row was not found in the table.
Raises:
IOError:An error occurred accessing the bigtable.Table object.
"""
pass
3) 块注释和行注释
最需要写注释的是代码中那些技巧性的部分,应该在实现前写上若干行注释. 对于那些不是一目了然的代码, 应在其行尾添加注释说明。
# We use a weighted dictionary search to find outwhere i is in
# the array. Weextrapolate position based on the largest num
# in the array and the array size and then do binarysearch to
# get the exact number.
if i & (i-1) == 0: # true iff i is a power of 2
4) 为了提高可读性, 注释应该至少离开代码2个空格.
5) 注释里不需要加代码实现的详细描述性的信息,可适当描述实现过程和功能。
# 不建议的注释: COMMENT: Now go through the b array and make sure whenever i occurs
# the next element is i+1
13.8 命名
1) 应该避免的名称
a) 单字符名称, 除了计数器和迭代器.
b) 包/模块名中的连字符(-)
c) 双下划线开头并结尾的名称(Python保留, 例如__init__)
2) 命名约定
a) 所谓”内部(Internal)”表示仅模块内可用, 或者, 在类内是保护或私有的.
b) 用单下划线(_)开头表示模块变量或函数是protected的(使用import * from时不会包含).
c) 用双下划线(__)开头的实例变量或方法表示类内私有.
d) 将相关的类和顶级函数放在同一个模块里. 不像Java, 没必要限制一个类一个模块.
e) 对类名使用大写字母开头的单词(如CapWords, 即Pascal风格), 但是模块名应该用小写加下划线的方式(如lower_with_under.py). 尽管已经有很多现存的模块使用类似于CapWords.py这样的命名, 但现在已经不鼓励这样做, 因为如果模块名碰巧和类名一致, 这会让人困扰.
3) Python之父Guido推荐的风格
类型 | 公用的 | 内部的 |
Modules | lower_with_under | _lower_with_under |
Packages | lower_with_under | |
Classes | CapWords | _CapWords |
Exceptions | CapWords | |
Functions | lower_with_under() | _lower_with_under() |
Global/Class Constants | CAPS_WITH_UNDER | _CAPS_WITH_UNDER |
Global/Class Variables | lower_with_under | _lower_with_under |
Instance Variables | lower_with_under | _lower_with_under (protected) or __lower_with_under (private) |
Method Names | lower_with_under() | _lower_with_under() (protected) or __lower_with_under() (private) |
Function/Method Parameters | lower_with_under | |
Local Variables | lower_with_under |
13.9 导入格式
1) 每个导入应该独占一行。
推荐方式:
import os
import sys
不建议方式:
import os, sys
2) 导入总应该放在文件顶部, 位于模块注释和文档字符串之后, 模块全局变量和常量之前. 导入应该按照从最通用到最不通用的顺序分组:
标准库导入、
第三方库导入、
应用程序指定导入
3) 每种分组中, 应该根据每个模块的完整包路径按字典序排序, 忽略大小写.
导入示例:
import foo
from foo import bar
from foo.bar import baz
from foo.bar import Quux
from Foob import ar
13.10 总结
本章我们学习如何优雅的进行python编程,接下来我们一起熟悉下Python里的常用关键字.