好的代码风格,给人舒服的感觉,今天介绍一下谷歌的Python风格规范,由于规范比较多,将分为两次介绍。
不要在行尾加分号, 也不要用分号将两条命令放在同一行。
每行不超过80个字符。
例外:
不要使用反斜杠连接行。
Python会将圆括号、中括号和花括号的行隐式的连接起来,可以利用这个特点。如果需要,可以在表达式外围增加一堆额外的圆括号。
如果一个文本字符串在一行放不下, 可以使用圆括号来实现隐式行连接:
x = ('This will build a very long long '
'long long long long long long string')
在注释中,如果必要,将长的URL放在一行上。
Yes:
# See details at
# http://www.example.com/us/developer/documentation/api/content/v2.0/csv_file_name_extension_full_specification.html
No:
# See details at
# http://www.example.com/us/developer/documentation/api/content/\
# v2.0/csv_file_name_extension_full_specification.html
注意上面例子中的元素缩进; 你可以在本文的 缩进部分找到解释。
宁缺毋滥得使用括号。
除非是用于实现行连接,否则不要在返回语句或条件语句中使用括号。不过在元组两遍使用括号是可以的。
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():
...
No:
if (x):
bar()
if not(x):
bar()
return (foo)
用四个空格来缩进代码。 绝对不要用tab,也不要tab和空格混用。对于行连接的情况,应该垂直对其换行的元素,或者使用4空格的悬挂式缩进:
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 dictionaryfoo = {
long_dictionary_key:
long_dictionary_value,
...
}
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,
...
}
顶级定义(比如函数或者类定义)之间空两行,方法定义之间空一行。
按照标准的排版规范来使用标点两边的空格。
大部分.py文件不必以#!作为文件的开始. 根据 PEP-394, 程序的main文件应该以 #!/usr/bin/python2或者 #!/usr/bin/python3开始。
注:在计算机科学中,Shebang(也称为 Hashbang )是一个由井号和叹号构成的字符序列 #! ,其出现在文本文件的第一行的前两个字符。 在文件中存在 Shebang 的情况下,类 Unix 操作系统的程序载入器会分析 Shebang 后的内容,将这些内容作为解释器指令,并调用该指令,并将载有 Shebang 的文件路径作为该解释器的参数。
#!先用于帮助内核找到Python解释器, 但是在导入模块时, 将会被忽略. 因此只有被直接执行的文件中才有必要加入#!。
确保对模块, 函数, 方法和行内注释使用正确的风格。
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."""
# We use a weighted dictionary search to find out where i is in
# the array. We extrapolate position based on the largest num
# in the array and the array size and then do binary search to
# get the exact number.
if i & (i-1) == 0: # true iff i is a power of 2
为了提高可读性,注释应该至少离开代码2个空格。
另一方面,绝不要描述代码。假设阅读代码的人比你更懂Python。 他只是不知道你的代码要做什么。
# BAD COMMENT: Now go through the b array and make sure whenever i occurs
# the next element is i+1
如果一个类不继承自其它类, 就显式的从object继承. 嵌套类也一样。
Yes:
class SampleClass(object):
passclass OuterClass(object):
class InnerClass(object):
passclass ChildClass(ParentClass):
"""Explicitly inherits from another class already."""No:
class SampleClass:
passclass OuterClass:
class InnerClass:
pass
继承自 object
是为了使属性(properties)正常工作, 并且这样可以保护你的代码, 使其不受 PEP-3000的一个特殊的潜在不兼容性影响。 这样做也定义了一些特殊的方法, 这些方法实现了对象的默认语义, 包括 __new__, __init__, __delattr__, __getattribute__, __setattr__, __hash__, __repr__, and __str__
。