如何正确遵守 Python 代码规范
作者:互联网
命名约定
- 函数名,变量名和文件名应该是描述性的,尽量避免缩写,除了计数器和迭代器、作为
try/except
中异常声明的e
以及作为with
语句中文件句柄的f
. - 用单下划线(_)开头表示变量或函数是 protected 的,不应该被外部访问(除了子类).
注释
函数和方法
一个函数必须要有文档字符串, 除非它满足以下条件:
- 外部不可见
- 非常短小
- 简单明了
文档字符串应该包含函数做什么,以及输入和输出的详细描述。通常,不应该描述“怎么做”,除非是一些复杂的算法。文档字符串应该提供足够的信息,当别人编写代码调用该函数时,他不需要看一行代码,只要看文档字符串就可以了。
文档字符串有多种风格,比如 Google 风格和 Numpy 风格,这里比较推荐 Numpy 风格的文档字符串,基本写法如下述代码所示:
复制def download_song(song_info: SongInfo, save_dir: str, quality=SongQuality.STANDARD) -> str:
""" download online music to local
Parameters
----------
song_info: SongInfo
song information
save_dir: str
directory to save the downloaded audio file
quality: SongQuality
song sound quality
Returns
-------
song_path: str
save path of audio file, empty string when the download fails
Raises
------
AudioQualityError:
thrown when the sound quality is illegal
"""
pass
块注释和行注释
最需要写注释的是代码中那些技巧性的部分,对于复杂的操作,应该在其操作开始前写上若干行注释。对于不是一目了然的代码, 应在其行尾添加注释。为了提高可读性, 注释应该至少离开代码 2 个空格。
复制# 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 if i is 0 or a power of 2.
另一方面,绝不要描述代码,阅读代码的人可能比你更懂 Python,他只是不知道你的代码要做什么.
复制# BAD COMMENT: increase i
i += 1
缩进
用 4 个空格来缩进代码,绝对不要用 tab, 也不要 tab 和空格混用。对于行连接的情况,应该垂直对齐换行的元素, 或者使用 4 空格的悬挂式缩进(这时第一行不应该有参数)。
哎呦不错哦:
复制# 垂直对齐参数
foo = long_function_name(var_one, var_two,
var_three, var_four)
# 字典内垂直对齐
foo = {
"long_dictionary_key": value1 +
value2,
...
}
# 4 个空格的悬挂缩进,左括号后面没有参数
foo = long_function_name(
var_one,
var_two,
var_three,
var_four
)
# 字典内 4 个空格的悬挂缩进
foo = {
"long_dictionary_key":
long_dictionary_value,
...
}
那种事情不要啊:
复制# 左括号后不能携带参数
foo = long_function_name(var_one, var_two,
var_three, var_four
)
# 禁止 2 个空格的悬挂式缩进
foo = long_function_name(
var_one,
var_two,
var_three,
var_four
)
# 字典内需要使用悬挂缩进
foo = {
"long_dictionary_key":
long_dictionary_value,
...
}
编写代码时不能缩进过多的层级,一般不要超过 4 层,不然会造成阅读困难。Python 中的缩进一般来自于 if-else
、for
和 while
等语句块,一种减少缩进的方法是写 if
就不写 else
,比如:
复制def update_by_ids(self, entities: List[Entity]) -> bool:
""" update multi records
Parameters
----------
entities: List[Entity]
entity instances
Returns
-------
success: bool
whether the update is successful
"""
# 不满足条件直接返回默认值
if not entities:
return True
# 假设这是一堆很复杂的业务代码
db = self.get_database()
db.transaction()
# 创建 sql 语句
id_ = self.fields[0]
values = ','.join([f'{i} = :{i}' for i in self.fields[1:]])
sql = f"UPDATE {self.table} SET {values} WHERE {id_} = :{id_}"
self.query.prepare(sql)
return db.commit()