技术: Python代码规范

分享一下我个人的编码习惯, Coding Rules.

注意本文和google的代码规范不一样, 本文是我根据网上多份代码参考, 以及结合自己的实际情况制定的.

引子

本文详细梳理了相关的规范, 有些明显的规则, 我就直接省略了(例如 “分号” 的使用)

正文

文件头的配置

1
2
3
4
5
6
#!/usr/local/bin/python2.7
#encoding:utf-8
#author:merlin

if __name__ == '__main__':
pass

#! 先用于帮助内核找到Python解释器, 但是在导入模块时, 将会被忽略. 因此只有被直接执行的文件中才有必要加入 #! .

空白和缩进

请用4个空格替换TAB
(注意第一行顶头写)

不换行

即便长度过长, 也不要使用反斜杠, 比如注释中的URL, 导入模块; 表达式过长的时候可以加括号(Python自动将过长的内容连接起来)
(条件表达式过长的时候, 才使用括号, 一般的if是可以不使用的)

总结就是, 行连接不适用左倒斜杠, 而是括号. (一般是圆括号, 当然也可以是其他的括号)

换行

换行的参数, 请对齐, 例如:

1
2
3
4
5
6
7
8
9
10
# 与起始变量对齐
foo = long_function_name(var_one, var_two,
var_three, var_four)

# 字典中与起始值对齐
foo = {
long_dictionary_key: value1 +
value2,
...
}

多行字符串也注意对齐

1
2
print ("This is much nicer.\n"
"Do it this way.\n")

空行

类与其他定义间空2行; 函数定义之间空1行.

空格

  • 括号内不要有空格;
  • 括号外: 变量名, 关键字, 符号之间都应该有空格. (但是贴着括号外的不要有空格)

(括号包括: 大括号, 中括号, 小括号)

(符号里默认参数的”=”两边不加括号)

编码

编码统一使用 utf-8

注释

一般要求

  • 注释不要求对齐 (如果在同一行, 那么至少保持两个空格的举例)
  • 注释一定不要使用中文
  • 给外部使用的方法一定要加上注释

函数注释

一般类或者方法的注释, 要使用文档注释(即三重双引号), 方便 pydoc 提取, 例如函数注释的模板可以是:
(注意第一行顶头写)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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

类注释

直接给出一个模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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 类.

1
2
class ChildClass(object):
"""Explicitly inherits from object."""

除了保证和python3的兼容性, 还可以有一些方法的默认实现(语义), 包括:

  • __init__
  • __new__
  • __del__
  • __hash__

等等.

命名规范

  • 目录名字全部小写, 单词(词组), 例如 resource
  • 内部方法和属性 _开头, 私有成分 __开头
  • 文件名, 单词(词组), 单词组合首字母大写(文件名不使用下划线), 例如 Driver.py
  • 类名中单词首字母大写, 例如 class DeviceDriver
  • 常量名使用大写和下划线, 例如 MAX_LEN
  • 变量名参数名字使用驼峰 shellConfig —-(注意这里区别于函数)
  • 变量名和参数名尽量不要缩写
  • 方法名字尽量小写, 单词之间下划线, 并且采用 动 + 宾 + 形容词 结构, 例如 check_user()
  • 在一个模块中集中内聚本包需要提供的接口, 例如 __init__.py 中 import 本包的其他接口, 外部使用该模块即可
  • 基础层, 领域层, 服务层, 需要向上汇报异常测试结果, 并且打印明确的报错信息
  • 服务层只返回结果, 用例来决定是否决定流程

用单下划线(_)开头表示模块变量或函数是protected的(使用import * from时不会包含)

Main函数

通常为了保证了脚本可重用, 最好把main函数内容封装一下, 也可以方便其他模块导入:

1
2
3
4
5
def main():
pass

if __name__ == '__main__':
main()

TODO

短期或者暂时的解决方案并不是很完美, 所以可以写一个 TODO 注释, 一定要写明自己名字或者Email地址.

1
TODO(merlin@gmail.com):todo sth

尾巴

仔细说下来, 要注意的事情貌似也没有那么多, 都习惯了.

文章目录
  1. 1. 引子
  2. 2. 正文
    1. 2.1. 文件头的配置
    2. 2.2. 空白和缩进
    3. 2.3.
      1. 2.3.1. 不换行
      2. 2.3.2. 换行
      3. 2.3.3. 空行
    4. 2.4. 空格
    5. 2.5. 编码
    6. 2.6. 注释
      1. 2.6.1. 一般要求
      2. 2.6.2. 函数注释
      3. 2.6.3. 类注释
    7. 2.7. 默认继承
    8. 2.8. 命名规范
    9. 2.9. Main函数
    10. 2.10. TODO
  3. 3. 尾巴
|