一、🔧 Ruff 能检查的部分 →
✅ 覆盖点
- 4 空格缩进(formatter)
- 行长度 100
- import 规则
- 命名风格
- 可变默认参数
- 布尔 / None / len 判断
- 异常明显错误
- 通配符 import
- 未使用变量
- 注释 / docstring(存在性 & 格式)
pyproject.toml
[tool.ruff]
line-length = 100
target-version = "py310"
# 启用规则集(按你规范精选)
select = [
"E", # pycodestyle errors(空格、缩进、换行)
"W", # pycodestyle warnings
"F", # Pyflakes(未使用变量、import)
"I", # isort(import 顺序)
"B", # flake8-bugbear(可变默认参数等)
"C4", # flake8-comprehensions
"UP", # pyupgrade
"SIM", # flake8-simplify(if/len/boolean 简化)
"RET", # return 规则(finally return 等)
"TRY", # try/except 反模式
"D", # pydocstyle(docstring)
"N", # pep8-naming(命名风格)
]
ignore = [
"D100", # 模块级 docstring(通常不强制)
"D104", # 包 __init__.py docstring
"D203", # 与 D211 冲突
"D213", # 与 D212 冲突
]
# 允许自动修复
fix = true
[tool.ruff.format]
indent-style = "space"
quote-style = "double"
line-ending = "lf"
skip-magic-trailing-comma = false
[tool.ruff.isort]
known-first-party = ["src"]
combine-as-imports = true
force-single-line = false
[tool.ruff.pydocstyle]
convention = "google"
[tool.ruff.flake8-bugbear]
extend-immutable-calls = ["Depends"]
[tool.ruff.pep8-naming]
classmethod-decorators = ["classmethod"]
[tool.ruff.per-file-ignores]
"tests/**.py" = ["D"]
能直接挡住的“坑”
| 你的规范 | Ruff 规则 |
|---|---|
| 禁止可变默认参数 | B006 |
| 禁止 if x is True | E712 |
| 禁止 len(x) == 0 | SIM108 |
| 禁止通配符 import | F403 |
| import 顺序 | I |
| 一个 import 一个模块 | E401 |
| finally 中 return | RET504 |
| 未使用变量 | F841 |
二、📋 Ruff 检查不了的 → Code Review Checklist
Python 代码规范(Ruff + PR Review 版)
目标:用工具兜底一致性,用 Review 保证质量****
适用范围:后端服务 / 脚本 / 中大型 Python 项目
规范治理原则
- 能自动化的,一定交给工具(Ruff / CI)
- 工具做不到的,才进入 Code Review
- Review 不纠结格式,只关注:设计、命名语义、异常、边界
自动化规范(Ruff 强制)
基础格式(强制)
-
统一使用 4 个空格缩进
-
单行最大长度 100
-
行过长时:
- 使用小括号 () 换行
- ❌ 禁止使用反斜杠 \
-
禁止在代码末尾加分号
-
禁止一行写多条语句
空行规则(强制)
- 函数之间:2 个空行
- 类之间:2 个空行
- 类中方法之间:1 个空行
- 函数内部:不同逻辑块可适当空行
空格规则(强制)
-
二元运算符两侧必须有空格
- 算术:+ - * / **
- 赋值:= += -=
- 比较:== != < > in is
- 逻辑:and or not
-
函数关键字参数 = 两侧不加空格
-
逗号后加空格(右括号除外)
-
冒号前无空格,冒号后一个空格(切片除外)
-
❌ 禁止为了对齐而添加多余空格
换行风格(推荐)
income = (
gross_wages
+ taxable_interest
+ (dividends - qualified_dividends)
- ira_deduction
- student_loan_interest
)
** 命名规范(格式级,Ruff 可检查)**
- 变量 / 函数:snake_case
- 类名:CamelCase
- 常量:ALL_CAPS_WITH_UNDERSCORES
- 模块名:全小写(可下划线)
- 包名:全小写(不推荐下划线)
- ❌ 禁止使用 l O I 作为单字符变量名
- ❌ 避免使用 xx(Python 保留)
2.6 Import 规范(强制)
-
一个 import 导入一个模块
-
import 必须位于文件顶部
-
顺序:
- 标准库
- 第三方库
- 本地应用
-
组之间空一行
-
❌ 禁止 from xxx import *
-
推荐使用绝对路径导入
** 函数与参数(强制)**
- ❌ 禁止使用 可变类型作为默认参数
# ❌ 错误示例
def func(items=[]):
pass
- 实例方法第一个参数必须是 self
- 类方法第一个参数必须是 cls
条件与布尔判断(强制)
- 判断空容器:
if not user_list:
pass
- ❌ 禁止 len(x) == 0
- 布尔值判断:
if is_active:
pass
- ❌ 禁止 if value is True
- None 判断:
if value is None:
pass
异常基础规则(Ruff 兜底)
- ❌ 禁止 finally 中 return
- ❌ 禁止捕获异常后什么都不做
- try/except 必须有明确处理逻辑
三、人工 Review 规范(PR Review Checklist)
⚠️ 以下内容 Ruff 无法检查,Reviewer 必须负责
3.1 设计与职责
- 每个函数是否只做一件事
- 是否存在明显超过 100 行的函数
- 是否可以拆分为更小函数
- 是否存在重复逻辑
3.2 控制流与异常
- 是否使用异常作为流程控制
- try/except 是否包裹过多代码
- except 是否真正处理异常
- 是否吞掉异常但无日志
3.3 命名语义(重点)
- boolean 是否使用 is_ / has_ / allow_
- id 是否使用 _id
- 数量是否使用 _count / _length
- 是否避免宽泛命名(data / info)
- 命名是否在 3–5 个单词以内
3.4 注释与文档
- 公共函数是否有 docstring
- 注释是否解释“为什么”
- 复杂逻辑是否有说明
- TODO 是否清晰表达未来意图
3.5 魔法值与常量
- 是否存在意义不明的数字
- 是否可以使用常量 / Enum
3.6 边界与健壮性
- 是否考虑 None / 空集合
- 是否存在潜在异常
- 外部依赖是否有保护
四、工具分工一览
| 工具 | 职责 |
|---|---|
| Ruff | 风格、import、低级 bug |
| Ruff Format | 缩进、空格、换行 |
| mypy | 类型与 None 安全 |
| radon | 圈复杂度 |
| Code Review | 设计、命名、异常策略 |
五、执行建议(强烈)
- 本地开发:
ruff check .
ruff format .
-
CI 必须阻断:
- Ruff 未通过
- Review Checklist 未完成
六、最终原则(必须遵守)
格式交给工具,质量交给人
不与 Ruff 争论,只讨论设计与语义