本指南提炼自 Google Python 风格指南,聚焦于提升代码健壮性与可维护性的强制约束,省略普遍已知的琐碎规则。
- 公共 API 必须标注
所有函数(包括__init__)的形参和返回值必须标注类型。类属性、模块级变量也须标注。 - 禁止
Any偷懒
除非类型真的任意,否则应使用具体类型、Optional、Union或Protocol。 - 启用静态检查
生成代码必须能通过mypy或pytype的严格模式,不允许类型错误遗留。 - 使用
from __future__ import annotations
让注解惰性求值,支持前向引用,避免循环导入。
Bad
def process(data):
...Good
from __future__ import annotations
def process(data: list[dict[str, int]], limit: int | None = None) -> dict[str, float]:
...- 模块 / 包:
lower_with_under.py - 类 / 异常:
CapWords(异常也应后缀Error,如ValueNotFoundError) - 函数 / 方法:
lower_with_under() - 全局常量:
UPPER_WITH_UNDER,定义在模块层级 - 变量:
lower_with_under - 私有成员:一律前缀单下划线
_,例如_helper()、_internal_var - 避免单字母变量(循环/推导式的迭代变量除外),严禁使用
l、O、I等易混淆字符
- 禁止多重
for出现在同一推导式
[x*y for x in ... for y in ...]直接禁止,必须拆解或用itertools.product。 - 禁止
map()/filter()搭配lambda
一律使用列表/集合/字典推导式或生成器表达式替代。 - 大数据流必须用生成器表达式
(...),禁止先构建完整列表。
- 循环中字符串拼接必须用
''.join() - 遍历字典键直接用
for key in adict:,禁止.keys() - 逐行读文件用
for line in file:,禁止.readlines() - 需要索引时用
enumerate(),禁止range(len(...))
凡多行控制流块(if / elif / else / for / while / with / try 等)的下方同级缩进必须增加一行 pass 作为显式块结束标记。
for x in arr:
print(x)
passif condition:
do_something()
else:
handle_other()
pass说明:该标记使块的边界一目了然,杜绝缩进混乱带来的隐蔽错误。
- 禁止可变默认参数
def f(a, cache={}):或cache=[]都是错误的,使用None+ 内部初始化。 - 参数中禁止传递可变对象引用
def f(items=some_global_list)应改用None或副本。 lambda仅限单行表达式,多行逻辑必须使用具名嵌套函数def。
Bad
def append_to(element, target=[]):
target.append(element)
return targetGood
def append_to(element, target=None):
if target is None:
target = []
target.append(element)
return target- 任何可关闭资源必须使用
with管理
文件、socket、锁等,禁止手动.close()/.acquire()/.release()。 - 生成器内避免直接持有外部资源,如需释放须通过
try-finally或上下文管理器包裹。
以下特性除非有明确文档且无法避免,否则严禁出现:
- 自定义元类
- 访问或修改字节码
exec()/compile()/eval()- 基于字符串的类型创建
type('Name', ...) - 直接操作
__dict__、栈帧 - 动态修改函数签名
- 公共模块、类、函数必须有文档字符串
按 Google 风格分段:Args:、Returns:、Raises:,不可省略。 - 禁止“重复型”注释
例如x += 1 # increase x直接删除。 - 复杂逻辑用注释解释“为什么”,而非“做什么”。
- 绝对禁止
from module import * - 每个导入独占一行,按顺序分组:标准库 → 第三方 → 本地,组间空一行
- 导入必须放在文件顶部,禁止在函数、类内部进行导入
- 禁止任何
sys.path修改的 hack
- 比较使用
is not而非not ... is - 判空直接使用隐式布尔值
if seq:而非if len(seq) > 0: - 异常必须指定具体类型,严禁裸
except:;重抛出用raise不带参数 - 行长度硬上限 80 字符,使用括号隐式续行,禁用反斜杠
\ - 括号内不得有多余空格,逗号后必须有空格
- 允许简单条件表达式
x = a if condition else b,但每部分必须保持一行