关于 python-clean-code
python-clean-code 是一项基于 Robert C. Martin 的 Clean Code 原则并适配 Python 的代码审查与编辑技能。它帮助开发者按规则编号识别问题,并在修改代码时说明修复内容。
主要功能
- 01涵盖注释、函数、命名、测试与设计
- 02针对导入、枚举和类型提示的 Python 规则
- 03按规则编号标记违规项
- 04修复说明关联相应规则编号
适用场景
- 01审查 Python 代码中的 Clean Code 问题
- 02重构参数过多或职责混杂的函数
- 03检查测试、命名和边界条件
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ ertugrul-dmr/ clean-code-skills --skill python-clean-code安装后在 Claude Code 中输入/python-clean-code确认已加载。
详细介绍
Python Clean Code:完整参考
强制执行 Robert C. Martin 第 17 章中的所有 Clean Code 原则,并针对 Python 进行了调整。
注释(C1-C5)
- C1:注释中不写元数据(使用 Git)
- C2:立即删除过时的注释
- C3:不写冗余注释
- C4:如果必须写注释,就要写好
- C5:绝不提交已注释掉的代码
环境(E1-E2)
- E1:用一条命令构建(
pip install -e ".[dev]") - E2:用一条命令测试(
pytest)
函数(F1-F4)
- F1:最多 3 个参数(参数更多时使用 dataclasses)
- F2:不使用输出参数(返回值)
- F3:不使用标志参数(拆分函数)
- F4:删除无用函数
通用原则(G1-G36)
- G1:每个文件只使用一种语言
- G2:实现预期行为
- G3:处理边界条件
- G4:不要绕过安全机制
- G5:DRY——不重复
- G6:抽象层级保持一致
- G7:基类不应了解子类
- G8:尽量缩小公共接口
- G9:删除无用代码
- G10:变量应靠近其使用位置
- G11:保持一致
- G12:清除冗余内容
- G13:避免人为耦合
- G14:避免特性嫉妒
- G15:不使用选择器参数
- G16:意图要清晰
- G17:代码放在符合预期的位置
- G18:优先使用实例方法
- G19:使用说明性变量
- G20:函数名应说明其功能
- G21:理解算法
- G22:让依赖关系显而易见
- G23:优先使用多态,而非 if/else
- G24:遵循约定(PEP 8)
- G25:使用命名常量,而非魔法数字
- G26:保持准确
- G27:结构优先于约定
- G28:封装条件判断
- G29:避免使用否定条件
- G30:函数只做一件事
- G31:明确表示时间上的耦合
- G32:避免随意行事
- G33:封装边界条件
- G34:每个函数只包含一个抽象层级
- G35:在较高层级配置
- G36:迪米特法则(避免链式调用)
Python 特有原则(P1-P3)
这些原则将 Java 特有规则(J1-J3)调整为符合 Python 约定的版本:
- P1:不使用通配符导入(
from x import *)——依据 PEP 8,这与 Java 相反 - P2:使用 Enums,而非魔法常量——与 J3 的原则相同
- P3:在公共接口上添加类型提示——相当于 Java 的静态类型
命名(N1-N7)
- N1:选择描述性名称
- N2:名称应符合抽象层级
- N3:使用标准命名
- N4:使用明确无歧义的名称
- N5:名称长度应与作用域匹配
- N6:不使用编码
- N7:名称应描述副作用
测试(T1-T9)
- T1:测试所有可能出问题的内容
- T2:使用覆盖率工具
- T3:不要跳过简单测试
- T4:被忽略的测试意味着存在待厘清的问题
- T5:测试边界条件
- T6:对容易出问题的部分进行穷尽测试
- T7:在失败中寻找规律
- T8:调试时检查覆盖率
- T9:测试必须快速(每项 < 100ms)
快速参考表
| 类别 | 规则 | 一句话概括 |
|---|---|---|
| 注释 | C1 | 不写元数据(使用 Git) |
| C3 | 不写冗余注释 | |
| C5 | 不提交已注释掉的代码 | |
| 函数 | F1 | 最多 3 个参数 |
| F3 | 不使用标志参数 | |
| F4 | 删除无用函数 | |
| 通用原则 | G5 | DRY——不重复 |
| G9 | 删除无用代码 | |
| G16 | 意图要清晰 | |
| G23 | 多态优先于 if/else | |
| G25 | 使用命名常量,而非魔法数字 | |
| G30 | 函数只做一件事 | |
| G36 | 迪米特法则(只用一个点) | |
| 命名 | N1 | 使用描述性名称 |
| N5 | 名称长度应与作用域匹配 | |
| 测试 | T5 | 测试边界条件 |
| T9 | 测试必须快速 |
反模式(不要这样做 → 应该这样做)
| ❌ 不要这样做 | ✅ 应该这样做 |
|---|---|
| 每行都写注释 | 删除显而易见的注释 |
| 为一行代码创建辅助函数 | 将代码直接内联 |
from x import * | 显式导入 |
魔法数字 86400 | SECONDS_PER_DAY = 86400 |
process(data, True) | process_verbose(data) |
| 深层嵌套 | 使用守卫子句和提前返回 |
obj.a.b.c.value | obj.get_value() |
| 100 行以上的函数 | 按职责拆分 |
AI 行为
审查代码时,按规则编号指出违规情况(例如:“违反 G5:逻辑重复”)。
修复或编辑代码时,报告修复内容(例如:“已修复:将魔法数字提取为 SECONDS_PER_DAY(G25)”)。
评论
支持 Markdown