Python代码规范笔记
1. 代码格式
- 缩进
使用4个空格
- 行宽
每行不超过80个字符(特殊情况不超过120)
以下情况除外:
长的导入模块语句
注释里的URL(在注释中,如果必要,将长的URL放在一行上)
- 引号
代码中多用单引号
自然语言使用双引号
正则表达式双引号
文旦注释三引号
- 空行
模块级函数和类定义之间空两行
类成员函数之间空一行
使用多个空行分隔多组相关的函数
函数中可以使用空行分隔逻辑相关代码
顶级定义之间空两行, 方法定义之间空一行
顶级定义之间空两行, 比如函数或者类定义. 方法定义, 类定义与第一个方法之间, 都应该空一行. 函数或方法中, 某些地方要是你觉得合适, 就空一行
class A:
def __init__(self):
pass
def hello(self):
pass
def main():
pass
2. import语句
- 放在文件头部
import os
import sys
from subprocess import Popen, PIPE
from foo.bar import Bar
import os
import sys
import msgpack
import zmq
import foo
from myclass import MyClass
import bar
import foo.bar
bar.Bar()
foo.bar.Bar()
3. 空格
i = i + 1
submitted += 1
x = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)
def complex(real, imag):
pass
def complex(real, imag=0.0):
pass
4. 换行
foo = long_function_name(var_one, var_two,
var_three, var_four)
def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)
session.query(MyTable).\
filter_by(id=1).\
one()
print 'Hello, '\
'%s %s!' %\
('Harry', 'Potter')
5. docstring
- 所有的公共模块、函数、类、方法,都应该写 docstring 。私有方法不一定需要,但应该在 def 后提供一个块注释来说明。
- docstring 的结束"""应该独占一行,除非此 docstring 只有一行。
"""Return a foobar
Optional plotz says to frobnicate the bizbaz first.
"""
"""Oneline docstring"""
6. 注释
- 块注释
“#”号后空一格,段落件用空行分开(同样需要“#”号)
- 行注释
至少使用两个空格和语句分开,注意不要使用无意义的注释
x = x + 1
- 建议
在代码的关键部分(或比较复杂的地方), 能写注释的要尽量写注释 比较重要的注释段, 使用多个等号隔开, 可以更加醒目, 突出重要性
app = create_app(name, options)
if __name__ == '__main__':
app.run()
- 文档注释(Docstring)
一般出现在模块头部、函数和类的头部,可以通过对象的__doc__对象获取文档,编辑器和IDE也可以根据Docstring给出自动提示 文档注释以 “”" 开头和结尾, 首行不换行, 如有多行, 末行必需换行, 以下是Google的docstring风格示例
"""Example docstrings.
This module demonstrates documentation as specified by the `Google Python
Style Guide`_. Docstrings may extend over multiple lines. Sections are created
with a section header and a colon followed by a block of indented text.
Example:
Examples can be given using either the ``Example`` or ``Examples``
sections. Sections support any reStructuredText formatting, including
literal blocks::
$ python example_google.py
Section breaks are created by resuming unindented text. Section breaks
are also implicitly created anytime a new section starts.
"""
具体描述其具体内容, 解释具体参数和返回值等
def function(a, b):
"""计算并返回a到b范围内数据的平均值"""
... ...
对函数参数、返回值等的说明采用numpy标准
def func(arg1, arg2):
"""在这里写函数的一句话总结(如: 计算平均值).
这里是具体描述.
参数
----------
arg1 : int
arg1的具体描述
arg2 : int
arg2的具体描述
返回值
-------
int
返回值的具体描述
参看
--------
otherfunc : 其它关联函数等...
示例
--------
示例使用doctest格式, 在`>>>`后的代码可以被文档测试工具作为测试用例自动运行
>>> a=[1,2,3]
>>> print [x + 3 for x in a]
[4, 5, 6]
"""
文档注释不限于中英文, 但不要中英文混用 文档注释不是越长越好, 通常一两句话能把情况说清楚即可 模块、公有类、公有方法, 能写文档注释的, 应该尽量写文档注释
-
文档注释 首先是一行以句号, 问号或惊叹号结尾的概述(或者该文档字符串单纯只有一行). 接着是一个空行. 接着是文档字符串剩下的部分, 它应该与文档字符串的第一行的第一个引号对齐 -
模块 每个文件应该包含一个许可样板. 根据项目使用的许可 -
函数和方法 一个函数必须要有文档字符串, 除非它满足以下条件: 1. 外部不可见 2. 非常短小 3. 简单明了 文档字符串应该包含函数做什么, 以及输入和输出的详细描述. 通常, 不应该描述"怎么做", 除非是一些复杂的算法. 文档字符串应该提供足够的信息, 当别人编写代码调用该函数时, 他不需要看一行代码, 只要看文档字符串就可以了. 对于复杂的代码, 在代码旁边加注释会比使用文档字符串更有意义. 关于函数的几个方面应该在特定的小节中进行描述记录, 这几个方面如下文所述. 每节应该以一个标题行开始. 标题行以冒号结尾. 除标题行外, 节的其他内容应被缩进2个空格. 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
- 类
类应该在其定义下有一个用于描述该类的文档字符串. 如果你的类有公共属性(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."""
如果一个类不继承自其它类, 就显式的从object继承. 嵌套类也一样.
class SampleClass(object):
pass
class OuterClass(object):
class InnerClass(object):
pass
class ChildClass(ParentClass):
"""Explicitly inherits from another class already."""
继承自 object 是为了使属性(properties)正常工作, 并且这样可以保护你的代码, 使其不受Python 3的一个特殊的潜在不兼容性影响. 这样做也定义了一些特殊的方法, 这些方法实现了对象的默认语义, 包括 new, init, delattr, getattribute, setattr, hash, repr, and str .
- TODO注释
为临时代码使用TODO注释, 它是一种短期解决方案. 不算完美, 但够好了. TODO注释应该在所有开头处包含"TODO"字符串, 紧跟着是用括号括起来的你的名字, email地址或其它标识符. 然后是一个可选的冒号. 接着必须有一行注释, 解释要做什么. 主要目的是为了有一个统一的TODO格式, 这样添加注释的人就可以搜索到(并可以按需提供更多细节). 写了TODO注释并不保证写的人会亲自解决问题. 当你写了一个TODO, 请注上你的名字.
如果你的TODO是"将来做某事"的形式, 那么请确保你包含了一个指定的日期(“2009年11月解决”)或者一个特定的事件(“等到所有的客户都可以处理XML请求就移除这些代码”).
7. 命名规范
- 模块
模块尽量使用小写命名,首字母保持小写,尽量不要用下划线(除非多个单词,且数量不多的情况)
import decoder
import html_parser
- 类名
类名使用驼峰(CamelCase)命名风格,首字母大写,私有类可用一个下划线开头
class Farm():
pass
class AnimalFarm(Farm):
pass
class _PrivateFarm(Farm):
pass
将相关的类和顶级函数放在同一个模块里
- 函数
函数名一律小写,如有多个单词,用下划线隔开
def run():
pass
def run_with_env():
pass
私有函数在函数前加一个下划线_
class Person():
def _private_func():
pass
- 变量名
变量名尽量小写, 如有多个单词,用下划线隔开
if __name__ == '__main__':
count = 0
school_name = ''
- 常量
常量采用全大写,如有多个单词,使用下划线隔开
MAX_CLIENT = 100
MAX_CONNECTION = 1000
CONNECTION_TIMEOUT = 600
|