python-best-practices
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePython Best Practices
Python最佳实践
Guidelines for writing and reviewing Python. 70 rules across 8 categories, prioritized by impact.
A rule match is a signal, not a verdict. Most rules are design preferences for new code, not bugs to fix across the repo — check the rule's impact level before flagging in review or refactoring stable code.
编写和评审Python代码的指南。涵盖8个分类共70条规则,按影响优先级排序。
规则匹配是一个信号而非定论。大多数规则是针对新代码的设计偏好,而非需要在整个仓库中修复的bug——在评审或重构稳定代码时,先检查规则的影响级别。
When to Apply
适用场景
- Writing new Python modules, functions, classes, or data models
- Reviewing code for correctness or type safety
- Refactoring patterns in code that's being edited anyway
Avoid applying these rules as a blanket sweep across stable code — the churn rarely pays off.
- 编写新的Python模块、函数、类或数据模型
- 评审代码的正确性或类型安全性
- 重构正在编辑的代码中的模式
不要将这些规则作为统一标准应用于所有稳定代码——这种改动通常得不偿失。
Impact Levels
影响级别
- — prevents a real bug class (data corruption, swallowed cancellations, insecure defaults). Fix when found.
CRITICAL - — meaningful correctness or maintainability win. Worth fixing in most contexts.
HIGH - — good practice; clarity or drift prevention. Apply to new code; don't churn stable code.
MEDIUM - /
LOW-MEDIUM— style or micro-optimizations. Apply opportunistically.LOW
- — 预防真实的bug类别(数据损坏、取消操作被吞、不安全默认值)。发现后需修复。
CRITICAL - — 在正确性或可维护性上有显著提升。大多数场景下值得修复。
HIGH - — 良好实践;提升清晰度或防止代码退化。应用于新代码;不要改动稳定代码。
MEDIUM - /
LOW-MEDIUM— 风格或微优化。适时应用。LOW
Python Version Baseline
Python版本基准
Rules assume Python 3.11+. Rules depending on higher versions call it out inline:
- — 3.13+
warnings.deprecated() - — 3.9+
zoneinfo - Union types in — 3.10+
isinstance() - — 3.11+ (backport via
assert_never)typing_extensions
Rules tagged are Pydantic-specific.
applicability:pydantic规则基于Python 3.11+制定。依赖更高版本的规则会在文中明确标注:
- — 3.13+
warnings.deprecated() - — 3.9+
zoneinfo - isinstance()中的联合类型 — 3.10+
- — 3.11+(可通过
assert_never向后兼容)typing_extensions
标记为的规则是Pydantic专属规则。
applicability:pydanticRule Categories by Priority
按优先级排序的规则分类
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | Data Modeling | HIGH | |
| 2 | Error Handling | MEDIUM-HIGH | |
| 3 | Type Safety | MEDIUM-HIGH | |
| 4 | API Design | MEDIUM | |
| 5 | Code Simplification | LOW-MEDIUM | |
| 6 | Performance | LOW-MEDIUM | |
| 7 | Naming | LOW-MEDIUM | |
| 8 | Imports & Structure | LOW | |
Section impact is a typical-case label; individual rules range one level above or below — check the rule file.
| 优先级 | 分类 | 影响级别 | 前缀 |
|---|---|---|---|
| 1 | 数据建模 | HIGH | |
| 2 | 错误处理 | MEDIUM-HIGH | |
| 3 | 类型安全 | MEDIUM-HIGH | |
| 4 | API设计 | MEDIUM | |
| 5 | 代码简化 | LOW-MEDIUM | |
| 6 | 性能优化 | LOW-MEDIUM | |
| 7 | 命名规范 | LOW-MEDIUM | |
| 8 | 导入与结构 | LOW | |
分类的影响级别是典型场景下的标签;单个规则的影响级别可能上下浮动一级——请查看规则文件确认。
Quick Reference
快速参考
Data Modeling (data-
)
data-数据建模 (data-
)
data-- — Never
data-mutable-defaults; usedef f(items=[])+ body construction orNonedefault_factory - — Compute booleans from state; don't cache flags that mirror each other
data-derive-dont-store - — Mutate OR return; not both
data-mutation-contract - — Timezone-aware
data-aware-datetimes;datetime.now(timezone.utc)is deprecatedutcnow() - — Tag variants instead of optional-field bags
data-discriminated-unions - — Concrete classes per mode beat
data-explicit-variants/is_threadflagsis_edit - — Group co-present optionals into one nested optional
data-phased-composition - — Trap mutable state in the narrowest clear scope
data-encapsulate-mutable-state - — Private sentinel when
data-sentinel-when-none-is-validis a meaningful valueNone - —
data-newtype-for-idsso IDs aren't interchangeableNewType('UserId', str) - — Remove union arms that aren't constructed
data-delete-dead-variants
- — 绝不要使用
data-mutable-defaults;使用def f(items=[])+ 函数体内构造或Nonedefault_factory - — 根据状态计算布尔值;不要缓存相互镜像的标志位
data-derive-dont-store - — 要么修改对象要么返回新对象;不要两者兼具
data-mutation-contract - — 使用时区感知的
data-aware-datetimes;datetime.now(timezone.utc)已被弃用utcnow() - — 为变体添加标签,而非使用可选字段集合
data-discriminated-unions - — 为每种模式创建具体类,优于
data-explicit-variants/is_thread标志位is_edit - — 将共存的可选字段分组到一个嵌套的可选结构中
data-phased-composition - — 将可变状态限制在最窄的明确范围内
data-encapsulate-mutable-state - — 当
data-sentinel-when-none-is-valid是有意义的值时,使用私有标记值None - — 使用
data-newtype-for-ids确保ID不可互换NewType('UserId', str) - — 移除未被构造的联合类型分支
data-delete-dead-variants
Error Handling (error-
)
error-错误处理 (error-
)
error-- — Catch specific types; never bare
error-specific-exceptionsorexcept:(breaks Ctrl-C and async cancellation);except BaseException:is cancellation-safe on 3.8+except Exception: - —
error-context-managers/withfor files, locks, sessionsasync with - —
error-assert-debug-onlyvanishes underassert; not for runtime contracts-O - — Fail fast at system edges before expensive work
error-validate-at-boundaries - — Trust immutable, locally-constructed state
error-trust-validated-state - — Merge blocks with the same catch and handling
error-consolidate-try-except - —
error-assert-never-exhaustivenessfor exhaustivenesstyping.assert_never - —
error-raise-from-for-chainsto preserve causalityraise NewErr(...) from original - — New exceptions inherit existing bases for compatibility
error-inherit-base-exceptions - —
error-log-exception-contextinsidelogger.exception(...); keep the traceback in the logexcept - —
error-repr-in-messagesfor identifiers in error textf"tool {name!r}"
- — 捕获特定类型;绝不要使用裸
error-specific-exceptions或except:(会破坏Ctrl-C和异步取消);Python 3.8+中except BaseException:是支持取消操作的except Exception: - — 对文件、锁、会话使用
error-context-managers/with上下文管理器async with - —
error-assert-debug-only在assert模式下会被移除;不要用于运行时契约-O - — 在执行昂贵操作前,在系统边界快速失败
error-validate-at-boundaries - — 信任不可变的、本地构造的状态
error-trust-validated-state - — 合并具有相同捕获逻辑的try-except块
error-consolidate-try-except - — 使用
error-assert-never-exhaustiveness确保穷尽性typing.assert_never - — 使用
error-raise-from-for-chains保留因果关系raise NewErr(...) from original - — 新异常继承现有基类以保证兼容性
error-inherit-base-exceptions - — 在
error-log-exception-context块内使用except;在日志中保留回溯信息logger.exception(...) - — 在错误文本中对标识符使用
error-repr-in-messages格式f"tool {name!r}"
Type Safety (types-
)
types-类型安全 (types-
)
types-- — Fix type errors;
types-fix-errors-not-ignoreis a last resort# type: ignore - — Protocols, TypeVars, unions over
types-avoid-anyAny - —
types-typeddict-over-dict-any/ dataclass when structure is knownTypedDict - —
types-literal-for-fixed-setsfor fixed stringsLiteral["a", "b"] - — Fix the definition;
types-fix-types-not-castonly when runtime genuinely narrowscast() - —
types-isinstance-for-narrowingoverisinstance()/hasattrtype(x).__name__ - — Annotations match what control flow actually allows
types-narrow-to-runtime-reality - — Drop runtime checks the types already enforce
types-trust-the-checker - — Drop
types-remove-redundant-optionalwhen values are guaranteed present| None - —
types-type-checking-importsfor optional or heavy importsif TYPE_CHECKING:
- — 修复类型错误;
types-fix-errors-not-ignore是最后的手段# type: ignore - — 使用Protocols、TypeVars、联合类型而非
types-avoid-anyAny - — 当结构已知时,使用
types-typeddict-over-dict-any/ dataclassTypedDict - — 对固定字符串集合使用
types-literal-for-fixed-setsLiteral["a", "b"] - — 修复定义;仅当运行时真正缩小类型范围时使用
types-fix-types-not-castcast() - — 使用
types-isinstance-for-narrowing而非isinstance()/hasattr进行类型收窄type(x).__name__ - — 注解与控制流实际允许的类型匹配
types-narrow-to-runtime-reality - — 移除类型检查器已能保证的运行时检查
types-trust-the-checker - — 当值确保存在时,移除
types-remove-redundant-optional| None - — 对可选或重量级导入使用
types-type-checking-importsif TYPE_CHECKING:
API Design (api-
)
api-API设计 (api-
)
api-- — Required fields before optional (Python enforces this)
api-required-before-optional - —
api-keyword-only-paramsmarker for optional/config params* - —
api-no-boolean-flag-params/LiteraloverEnumsoupTrue, False - — Return new collections; don't mutate inputs
api-immutable-transforms - — Flat models; no duplicate or single-key-wrapped fields
api-model-cohesion - —
api-underscore-for-privatefor internals; exclude from_prefix__all__ - —
api-deprecated-aliases(3.13+) for renamed APIswarnings.deprecated() - — Don't reach into
api-no-private-accessnames from outside the module_prefixed - — Pick the namespace that matches ownership
api-instance-vs-module-fn
- — 必填字段放在可选字段之前(Python强制要求)
api-required-before-optional - — 使用
api-keyword-only-params标记可选/配置参数* - — 使用
api-no-boolean-flag-params/Literal而非大量Enum参数True, False - — 返回新集合;不要修改输入
api-immutable-transforms - — 使用扁平模型;不要有重复或单键包装的字段
api-model-cohesion - — 使用
api-underscore-for-private标记内部实现;从_前缀中排除__all__ - — 对重命名的API使用
api-deprecated-aliases(3.13+)warnings.deprecated() - — 不要从模块外部访问
api-no-private-access命名的对象_前缀 - — 选择与所有权匹配的命名空间
api-instance-vs-module-fn
Code Simplification (simplify-
)
simplify-代码简化 (simplify-
)
simplify-- — Return early; don't nest the happy path
simplify-early-return - — Second copy is the decision point; third is the safe default
simplify-extract-after-duplication - —
simplify-cached-propertyon immutable instances; not thread-safe@cached_property - — Comprehensions over
simplify-comprehensions+for.append() - —
simplify-any-all-builtins/any()over manual flag +all()break - —
simplify-fallback-orwhen falsy values aren't semanticx or default - —
simplify-flatten-nested-ifwhen no intervening codeif cond1 and cond2: - — Drop intermediates used once
simplify-inline-single-use-vars - — Delete commented-out code; git preserves history
simplify-remove-dead-code
- — 提前返回;不要将正常路径嵌套
simplify-early-return - — 出现第二次重复时考虑提取;第三次重复时默认提取
simplify-extract-after-duplication - — 在不可变实例上使用
simplify-cached-property;注意它不是线程安全的@cached_property - — 使用推导式而非
simplify-comprehensions+for.append() - — 使用
simplify-any-all-builtins/any()而非手动标记 +all()break - — 当假值无语义时,使用
simplify-fallback-orx or default - — 当没有中间代码时,使用
simplify-flatten-nested-ifif cond1 and cond2: - — 移除仅使用一次的中间变量
simplify-inline-single-use-vars - — 删除注释掉的代码;git会保留历史记录
simplify-remove-dead-code
Performance (perf-
)
perf-性能优化 (perf-
)
perf-- —
perf-set-for-membershipfor repeatedsetchecksin - — Build a
perf-dict-index-over-nested-loopsfor lookupsdict - —
perf-lru-cache-pure-fns/functools.lru_cacheon pure functionsfunctools.cache - — Stream with generators when memory or latency matters
perf-generator-over-list - — Fuse
perf-combine-iterations+filterinto one passmap - — Compile static regex at module scope; matters in tight loops
perf-compile-regex-module-level - — Module-scope
perf-type-adapter-constant(applicability: pydantic)TypeAdapter - — Tuple form is marginally faster; profiled hot paths only
perf-isinstance-tuple-syntax
- — 对重复的
perf-set-for-membership检查使用inset - — 构建
perf-dict-index-over-nested-loops用于查找dict - — 对纯函数使用
perf-lru-cache-pure-fns/functools.lru_cachefunctools.cache - — 当内存或延迟很重要时,使用生成器流式处理
perf-generator-over-list - — 将
perf-combine-iterations+filter合并为一次遍历map - — 在模块作用域编译静态正则表达式;在密集循环中效果显著
perf-compile-regex-module-level - — 在模块作用域定义
perf-type-adapter-constant(applicability: pydantic)TypeAdapter - — 元组形式速度略快;仅在经过性能分析的热点路径中使用
perf-isinstance-tuple-syntax
Naming (naming-
)
naming-命名规范 (naming-
)
naming-- — Rename when behavior changes; stale names mislead
naming-rename-on-behavior-change - — Same concept, same word across code/docs/errors
naming-consistent-terminology - —
naming-specific-over-generic; not baretoolset_idid - —
naming-drop-redundant-prefixes; notToolConfig.descriptionToolConfig.tool_description - —
naming-upper-case-constants;MAX_RETRIESprefix for internal_ - — No
naming-no-type-suffixes/_dictsuffixes; types annotate types_list
- — 当行为改变时重命名;过时的名称会误导他人
naming-rename-on-behavior-change - — 在代码/文档/错误信息中,同一概念使用相同术语
naming-consistent-terminology - — 使用
naming-specific-over-generic;不要使用裸toolset_idid - — 使用
naming-drop-redundant-prefixes;不要使用ToolConfig.descriptionToolConfig.tool_description - — 使用
naming-upper-case-constants;内部常量使用MAX_RETRIES前缀_ - — 不要使用
naming-no-type-suffixes/_dict后缀;类型由注解说明_list
Imports & Structure (imports-
)
imports-导入与结构 (imports-
)
imports-- — Modules must be cheap to import — no network/model/env reads at import
imports-no-side-effects - — Imports at the top; documented exceptions for circular / optional / deferred
imports-top-of-file - —
imports-optional-dependencies/trywith install hintsexcept ImportError - — Define helpers near where they're used
imports-scope-helpers-to-usage - — Delete unused imports
imports-remove-unused - — One import per name
imports-no-duplicates
- — 模块导入必须轻量化——导入时不要进行网络/模型/环境读取操作
imports-no-side-effects - — 导入放在文件顶部;循环依赖、可选依赖、延迟导入等情况需注明
imports-top-of-file - — 使用
imports-optional-dependencies/try并提供安装提示except ImportError - — 在使用辅助函数的附近定义它们
imports-scope-helpers-to-usage - — 删除未使用的导入
imports-remove-unused - — 每个名称仅导入一次
imports-no-duplicates
How to Use
使用方法
Read individual rule files for detail:
rules/data-mutable-defaults.md
rules/error-specific-exceptions.mdEach rule has:
- Impact level in frontmatter
- Brief explanation
- Incorrect example
- Correct example
- Optional note on edge cases
For the full compiled guide with all rules expanded: .
AGENTS.md查看单个规则文件获取详细信息:
rules/data-mutable-defaults.md
rules/error-specific-exceptions.md每个规则包含:
- 前置元数据中的影响级别
- 简要说明
- 错误示例
- 正确示例
- 可选的边缘情况说明
如需查看包含所有展开规则的完整编译指南,请参考:。
AGENTS.md