意淫系列-Python 编码规范(Google)
Python 风格规范,是编写Python时高效性能的一个体现。写几点比较常用,且会常常犯的错误
空行
顶级定义之间空两行,方法定义之间空一行
注释
确保对模块,函数,方法和行内注释使用正确的风格
文档字符串
Python有一种独一无二的注释方式:使用文档字符串。文档字符串是包,模块,类或者函数里的第一个语句。这些字符串可以通过对象的__doc__成员被自动提取,并且被pydoc使用。
模块
每个文件应该包含一个许可样本。根据项目使用的许可选择合适的样版
函数和方法
一个函数必须要有稳定字符串,除非它满足一下条件:
1,外部不可见
2,非常小
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 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
类
类应该在其定义下有一个用于描述该类的文档字符串,如果你的类有公共属性,那么文档中应该有一个属性段,并且应该遵守和函数参数相同的格式。
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."""
块注释和行注释
对于复杂的操作,应该在其操作开始前写上若干行注释,对于不是一目了然的代码,应该在其行尾添加注释
类
如果一个类不继承其他类,就显示的从object继承。嵌套类也是一样的。
Yes: class SampleClass(object):
pass
class OuterClass(object):
class InnerClass(object):
pass
class ChildClass(ParentClass):
"""Explicitly inherits from another class already."""
字符串
多采用.format格式控制
Yes: 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)
文件和socket
在文件和sockets结束的时候,显示地关闭它。
除文件外,sockets或其他类似文件的对象在没有必要的情况下打开,会有许多副作用。例如:
- 它们可能会消耗有限的系统资源,如文件描述符。如果这些资源在使用后没有及时归还给系统,那么用于处理这些对象的代码会将资源消耗殆尽
- 持有文件将会阻止对于文件的其他操作
- 仅仅是从逻辑上关闭文件和sockets,那么它们仍然可能会被其他共享的程序在无意中进行读或者写操作。只有当他们真正被关闭后,对于尝试进行读或者写操作将会跑出异常,并且使得问题显现。
导入格式
每个导入应该是独占一行
导入总应该放在文件顶部,位于模块注释和文档字符串之后,模块全局变量和常量之前。导入应该从最通用到最不通用的顺序组:
- 标准库导入
- 第三方库导入
- 应用程序指定导入
命名
module_name,package_name,ClassName,method_name,ExceptionName,function_name,GLOBAL_VAR_NAME...
应该避免的名称
- 单字符名称
- 包/模块名中的连字符(-)
- 双下划线开头并结尾的名称(python 保留,例如__init__)
命名约定
- 所谓的内部表示仅模块内可使用,或者在类内饰保护的或者私有的
- 用单下划线开头表示模块变量或者函数是protected的
- 用双下划线开头的实例变量或者方法表示类内私有的
- 对类名使用大写字母开头的单词,但是模块名应该用小写加下划线的方法,尽管已经存在很多模块使用类似于CapWord.py这样的命名,但是现在不鼓励这样做,如果模块名碰巧和类名一致这样会比较困扰。
推荐命名规则
Type | Public | Internal |
---|---|---|
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 |