用途
该技能用于回答“这段 Python 代码是否干净且正确”这类问题,属于评审导向的技能。它覆盖的是评审者或 linter 应当标记的正确性与可读性缺陷,与测试机制(pytest)和整库健康度评分(code-quality-scoring)区分开来。
适用场景包括:
- 评审拉取请求并检查下列缺陷。
- 在提交 PR 前进行自查。
- 配置 ruff/pylint/mypy 规则,让 CI 自动捕获这些问题。
- 编写或更新团队的 Python 代码质量指南。
不适用于测试机制(应使用 pytest 技能),也不适用于为整个代码库的健康度与技术债评分(应使用 code-quality-scoring 技能)。
主要能力:六类核心反模式
技能总结了六个最高价值的 Python 反模式,每个都配有不合规/合规示例以及“如何测试”的说明:
- 自定义异常必须继承自 Exception。一个本意用于 raise 的类若继承自 object,会在运行时失败并破坏所有 except 子句。
- 单例应使用 is 比较,而非 ==。对 None/True/False 使用 is/is not(PEP 8);is 仅用于单例,绝不用于值比较。
- 避免裸 except 或过宽的 except。捕获你能处理的最窄类型;通用的 except Exception 仅作为最后位置的兜底,用于记录日志或重新抛出。
- 避免通配符导入(from x import *)。它们隐藏依赖、带来静默名称冲突风险,并使静态分析失效。
- 用命名常量替代魔法数字。将不明显的字面量提升为有文档说明的命名常量。
- 移除未使用的局部变量。死赋值会误导读者,并可能掩盖本应使用某值的 bug。
使用方式与最佳实践
- 在 CI 中设置门禁。多数问题可用 ruff(F403/F405 通配符、F841 未使用局部变量、E711/E712 单例比较)、pylint 和 mypy 低成本强制执行。将 lint 步骤放入 CI,使评审精力集中在判断而非机械检查上。
- 优先使用具体的异常处理器。处理器按从最窄到最宽排序;将通用 except Exception 保留为记录日志/重新抛出的最后手段。
- 命名意图,而非值。常量的名称记录了阈值存在的原因;裸字面量什么也说明不了。
应避免的反模式
- 自定义异常继承自 object 或直接继承自 BaseException。
- == None、== True 或 is "某个字面量"。
- 裸 except: 或 except BaseException: 吞掉控制流信号。
- 在带有显式 all 的受控 init.py 之外使用 from module import *。
- 业务逻辑中未加解释的数字字面量。
- 陈旧重构遗留的已赋值但从未读取的局部变量。
导航与相关技能
- quality-antipatterns.md:六个反模式的完整不合规与合规示例,以及每个反模式的“如何测试”说明。
- 相关技能:pytest(toolchains/python/testing/pytest)负责测试机制——fixture、参数化、mock;此处若干反模式(过宽 except、异常类定义错误)会直接导致测试不稳定。code-review-standards(universal/process/code-review-standards)是项目级、带严重度标签的评审清单,纳入了这些反模式的等价项。code-quality-scoring(universal/quality/code-quality-scoring)负责整库健康度与技术债评分,而非单条发现。
来源说明
这些反模式源自 CAST Highlight 的 Python 代码质量指标(https://doc.casthighlight.com/),其首要参考来源为 PEP 8 和 Python 数据模型。当某条规则与 PEP 8 一致时,以 PEP 为准。所有示例均为原创。