Python 代码规范

updated: 09/04/2019.

命名规范

模块/文件

  • 尽量使用小写命名首字母保持小写尽量不要用下划线(除非多个单词,且数量不多的情况)。
1
2
3
4
5
6
# 示例
import decoder
import html_parser

# 不推荐
import Decoder

类型

  • 类名使用驼峰命名风格,首字母大写私有类可用一个下划线开头

  • 将相关的类和顶级函数放在同一个模块里, 没必要限制一个类一个模块。

1
2
3
4
5
6
7
8
9
10
# 类名用驼峰命名风格
class Farm():
pass

class AnimalFarm(Farm):
pass

# 私有类加下划线
class _PrivateFarm(Farm):
pass

函数

  • 函数名一律小写,如有多个单词,用下划线隔开
  • 私有函数在函数前加一个下划线_
1
2
3
4
5
6
7
8
9
# 函数名,小写单词下划线隔开
def run_with_env():
pass


class Person():
# 私有函数加下划线
def _private_func():
pass

变量名

  • 变量名尽量小写, 如有多个单词,用下划线隔开

  • 常量采用全大写,如有多个单词,用下划线隔开

  • 为了说明变量的作用域,可以加前缀以示说明:
变量类型 前缀 示例
整型 n_ n_count
浮点型 f_ f_rate
字符串 s_ s_input
局部 _ _temp
全局 g_ g_count
1
2
3
4
if __name__ == '__main__':
n_count = 0
s_school_name = ''
MAX_CLIENT = 100

注释

代码注释

块注释

  • “#”号后空一格,段落间用空行分开(同样需要“#”号)。
1
2
3
4
# 这是块注释的第一句,还没结束。
# 这是块注释的第二句,还没结束。
#
# 这是块注释的下一段,快结束了。

行注释

  • 至少使用两个空格和语句分开,注意不要使用无意义的注释。
1
x = x + 1  # 行注释至少空两个空格

提醒注释

  • 在代码的关键部分(或比较复杂的地方), 能写注释的要尽量写注释。
  • 比较重要的注释段, 使用多个等号隔开, 可以更加醒目, 突出重要性。
1
2
3
4
5
6
7
# =====================================
# 请勿在此处添加 get post等app路由行为 !!!
# =====================================

if __name__ == '__main__':
# TODO: ADDA Segmentation Network 实现。
app.run()

文档注释

  • 一般出现在模块头部、函数和类的头部。
  • 以 “”” 开头和结尾, 首行不换行, 如有多行, 末行必需换行。
  • 不限于中英文, 但不要中英文混用。
  • 模块、公有类、公有方法, 能写文档注释的, 应该尽量写文档注释。
  • 具体可参照以下示例。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# -*- coding: utf-8 -*-
"""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.
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def he_normal(seed=None):
"""He normal initializer.

It draws samples from a truncated normal distribution centered on 0
with `stddev = sqrt(2 / fan_in)`
where `fan_in` is the number of input units in the weight tensor.

# Arguments
seed: A Python integer. Used to seed the random generator.

# Returns
An initializer.

# References
He et al., http://arxiv.org/abs/1502.01852
"""
pass
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
class Conv2D(_Conv):
"""2D convolution layer (e.g. spatial convolution over images).

This layer creates a convolution kernel that is convolved
with the layer input to produce a tensor of
outputs. If `use_bias` is True,
a bias vector is created and added to the outputs. Finally, if
`activation` is not `None`, it is applied to the outputs as well.

When using this layer as the first layer in a model,
provide the keyword argument `input_shape`
(tuple of integers, does not include the sample axis),
e.g. `input_shape=(128, 128, 3)` for 128x128 RGB pictures
in `data_format="channels_last"`.

# Arguments
filters: Integer, the dimensionality of the output space
(i.e. the number of output filters in the convolution).
kernel_size: An integer or tuple/list of 2 integers, specifying the
height and width of the 2D convolution window.
Can be a single integer to specify the same value for
all spatial dimensions.
strides: An integer or tuple/list of 2 integers,
specifying the strides of the convolution
along the height and width.
Can be a single integer to specify the same value for
all spatial dimensions.
Specifying any stride value != 1 is incompatible with specifying
any `dilation_rate` value != 1.
padding: one of `"valid"` or `"same"` (case-insensitive).
Note that `"same"` is slightly inconsistent across backends with
`strides` != 1, as described
[here](https://github.com/keras-team/keras/pull/9473#issuecomment-372166860)
data_format: A string,
one of `"channels_last"` or `"channels_first"`.
The ordering of the dimensions in the inputs.
`"channels_last"` corresponds to inputs with shape
`(batch, height, width, channels)` while `"channels_first"`
corresponds to inputs with shape
`(batch, channels, height, width)`.
It defaults to the `image_data_format` value found in your
Keras config file at `~/.keras/keras.json`.
If you never set it, then it will be "channels_last".
dilation_rate: an integer or tuple/list of 2 integers, specifying
the dilation rate to use for dilated convolution.
Can be a single integer to specify the same value for
all spatial dimensions.
Currently, specifying any `dilation_rate` value != 1 is
incompatible with specifying any stride value != 1.
activation: Activation function to use
(see [activations](../activations.md)).
If you don't specify anything, no activation is applied
(ie. "linear" activation: `a(x) = x`).
use_bias: Boolean, whether the layer uses a bias vector.
kernel_initializer: Initializer for the `kernel` weights matrix
(see [initializers](../initializers.md)).
bias_initializer: Initializer for the bias vector
(see [initializers](../initializers.md)).
kernel_regularizer: Regularizer function applied to
the `kernel` weights matrix
(see [regularizer](../regularizers.md)).
bias_regularizer: Regularizer function applied to the bias vector
(see [regularizer](../regularizers.md)).
activity_regularizer: Regularizer function applied to
the output of the layer (its "activation").
(see [regularizer](../regularizers.md)).
kernel_constraint: Constraint function applied to the kernel matrix
(see [constraints](../constraints.md)).
bias_constraint: Constraint function applied to the bias vector
(see [constraints](../constraints.md)).

# Input shape
4D tensor with shape:
`(batch, channels, rows, cols)`
if `data_format` is `"channels_first"`
or 4D tensor with shape:
`(batch, rows, cols, channels)`
if `data_format` is `"channels_last"`.

# Output shape
4D tensor with shape:
`(batch, filters, new_rows, new_cols)`
if `data_format` is `"channels_first"`
or 4D tensor with shape:
`(batch, new_rows, new_cols, filters)`
if `data_format` is `"channels_last"`.
`rows` and `cols` values might have changed due to padding.
"""

代码风格

编码

  • 一律采用UTF-8编码。
  • 文件头部建议加入 #-*-coding:utf-8-*-标识

缩进

  • 使用4个空格,而非TAB

行宽

  • 建议每行代码不超过80个字符(参考PyCharm中的参考线),超过用 \ 换行。

引号

  • 自然语言使用双引号"..."
  • 代码常规字符用单引号'...'
  • 正则表达式使用双引号r"..."
  • 文档字符串(docstring)使用三个双引号"""......"""
1
2
3
4
5
6
7
8
# 自然字符串用双引号
a = u"中山大学"

# 一般用单引号
maps = {'Guangdong': 'Guangzhou'}

# 正则表达式用双引号
pat = re.compile(r"\d{1,3}\t\s.+?,")

空行

  • 类定义末尾空两行。
  • 类内函数之间空一行。
  • 类外函数之间空两行。
  • 函数内部逻辑相关的可以用空行间隔。
  • 多个相关的函数可用多个空行间隔。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class A(object):

def __init__(self):
pass

def func(self):
pass


def func1():
pass


def func2():
pass


if __name__ == "__main__":
pass

import

  • 一条import写一行,多个import不要写到一行中去。
  • 建议import的优先级: python自带的模块 > 第三方模块 > 自定义模块。酶类模块之间用空格分开。
  • 不建议用相对引用,除了自己封装的库内。
  • 注意不要因为多个import引起的命名冲突。
1
2
3
4
5
6
7
import os
import sys

import numpy as np
import matplotlib.pyplot as plt

from mymodule import core, utils

空格

  • 二元运算符两边各空一格:=, -, *, /, +=, -=, ==, >, <, >=, <=, in, is, not, and
  • 逗号,之后留一个空格。
  • 括号不用空格。
  • 函数的形参中,默认值等号两边不要加空格。
  • 不要强行为了对齐而空格。
  • 在中文注释中,英文字符左右各空一格。
1
2
3
4
5
6
7
x = x * x + 1
c = (a + b) ** 2

def func(a, c=5):
pass

# 这个注释中,使用 a 这个变量。

换行缩进

  • 第二行缩进到括号起始处。
  • 第二行缩进 4 个空格,适用于起始括号就换行处。
  • 使用反斜杠\换行时,+. 等运算符应该出现在行末。
  • 严禁一行多句。
  • if/for/while 必须换行。
1
2
3
4
5
6
7
8
9
10
11
12
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)

print ('Hello, '\
'%s %s!' %\
('Harry', 'Potter')
)