一键导入
python-coding-standards
在编写、修改或评审 Python 代码(模块、包、pytest 测试、pyproject 配置)时使用。提供可变默认参数、类型注解、异常与 EAFP、资源管理、相等与身份、数据容器、导入与 PEP 8 命名、并发的具体规则与正反例。静态类型语言规则见对应语言技能。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
在编写、修改或评审 Python 代码(模块、包、pytest 测试、pyproject 配置)时使用。提供可变默认参数、类型注解、异常与 EAFP、资源管理、相等与身份、数据容器、导入与 PEP 8 命名、并发的具体规则与正反例。静态类型语言规则见对应语言技能。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
在规格、设计、测试或代码需要独立评审时使用:阶段产物完成后的把关、人要求 review、或对既有产物做专项检查时。评审必须由作者之外的独立上下文执行,产出 findings 与 verdict。
在实现任何功能或修复任何缺陷、即将编写实现代码时使用;设计确认后的整个实现期都适用。强制测试先行的 RED→GREEN→REFACTOR 循环。不用于规格编写、设计决策或纯文档修改。
在车载软件工作项(ECU、域控、车载服务、整车平台)的规格、设计、实现或评审中使用,涉及功能安全/ASIL、车载 SOA 服务、DTC/诊断、整车启动/休眠/唤醒、SELinux 或跨 ECU 协同时。只承载车载专属约束;内存/实时性、通用服务接口或其他相邻领域规则由命中 description 的领域技能叠加,语言级规则见适用 `<language>-coding-standards`。
在后端/服务端工作项(HTTP/REST/GraphQL API、服务与仓库层、数据库访问、缓存、鉴权、限流、后台任务、可观测性、配置与机密、弹性容错、生产就绪)的规格、设计、实现或评审中使用,涉及接口契约、分层与依赖方向、配置与机密、错误模型、数据一致性、幂等、认证授权、依赖超时重试熔断、过载保护、优雅停机时。只承载服务端/API 领域约束;客户端/UI、行业专属服务或其他相邻领域规则由命中 description 的领域技能叠加,语言级规则见适用 `<language>-coding-standards`。
在编写、修改或评审 C 代码(.c 源文件、.h 头文件、C 单元测试、C ABI 边界)时使用。提供指针所有权、手动内存与资源释放、缓冲区容量、整数转换、宏、头文件、错误返回的具体规则与正反例。只适用于 C 语言;其他语言或 C++ 代码使用对应语言自己的 coding-standards 技能。
在需要为某种编程语言新建或修订 coding-standards 技能时使用:把团队内部编码规范文档转化为符合 DevFlow 形态的 <language>-coding-standards 技能,或把新的团队规则并入既有语言技能。不用于编写业务代码或直接做代码评审。
| name | python-coding-standards |
| description | 在编写、修改或评审 Python 代码(模块、包、pytest 测试、pyproject 配置)时使用。提供可变默认参数、类型注解、异常与 EAFP、资源管理、相等与身份、数据容器、导入与 PEP 8 命名、并发的具体规则与正反例。静态类型语言规则见对应语言技能。 |
Python 的核心危险是动态与隐式:错误延迟到运行期才暴露,可变共享状态在背后累积。本技能在 devflow-clean-code 的通用标准之上叠加 Python(3.9+)语言规则,不能替代通用 clean-code 自检;每条规则针对一类真实事故(跨调用状态污染、运行期类型错误、被吞异常、资源泄漏、身份/相等混淆)。项目声明了 PEP 8 / 团队规范子集时以项目为准,本文是未声明时的默认底线。
默认参数在函数定义时求值一次,可变默认值会在调用间累积——经典事故:
# ❌ 同一个 list 被所有调用共享,跨调用累积
def append_to(item, items=[]):
items.append(item)
return items
# ✅ 用 None 哨兵,每次新建
def append_to(item, items=None):
if items is None:
items = []
items.append(item)
return items
None、数字、字符串、元组)__init__ 里创建,或用 dataclass 的 field(default_factory=list)frozenset / frozen=True 的 dataclass 表达,避免别名修改注解是给 mypy 和读者的契约,缺失时类型错误拖到运行期:
# ❌ 无注解,参数与返回类型靠猜,IDE/mypy 无法检查
def process(user_id, data, active=True):
...
# ✅ 公共函数签名全注解;3.9+ 用内置泛型,可缺失值用 | None
def process(user_id: str, data: dict[str, Any], active: bool = True) -> User | None:
...
mypy(或 pyright)在 CI 校验Any 逃避类型检查;确实动态时用 object 或 Protocol 表达约束typing.Protocol(结构化鸭子类型)而非继承Python 偏好 EAFP(先做再处理异常)而非过度前置检查;但捕获必须精确:
# ❌ 裸 except 吞掉一切(含 KeyboardInterrupt/SystemExit),掩盖 bug
try:
risky()
except:
pass
# ✅ 捕获具体异常;包装时用 from 保留异常链
try:
return Config.from_json(read(path))
except FileNotFoundError as e:
raise ConfigError(f"config not found: {path}") from e
except json.JSONDecodeError as e:
raise ConfigError(f"invalid JSON: {path}") from e
except: 或 except Exception: pass;捕获最具体的异常raise NewError(...) from e 保留 tracebackclass AppError(Exception))再派生,便于边界统一捕获# ❌ 手动 open/close:异常时漏关
f = open(path)
data = f.read()
f.close()
# ✅ with 上下文管理器,异常路径也释放
with open(path) as f:
data = f.read()
with;多个资源用嵌套或 with a, b:__enter__/__exit__,或用 @contextlib.contextmanager;__exit__ 返回 falsy(不吞异常,除非有意)# ❌ 用 == 比较 None / 用 is 比较值
if value == None: ...
if name is "admin": ... # 字符串驻留是实现细节,不可靠
# ✅ is 只用于 None 和单例;== 用于值比较
if value is None: ...
if name == "admin": ...
is/is not 只用于 None、True/False 单例的判定;其余值比较用 ==isinstance(x, T),不用 type(x) == T(破坏子类与多态)# ❌ 用裸 dict/tuple 在层间传业务对象,字段靠约定,拼写错误静默
user = {"id": "1", "naem": "Alice"} # 拼错 key 不报错
# ✅ dataclass:字段、类型、__init__/__repr__/__eq__ 自动且受检
from dataclasses import dataclass
@dataclass(frozen=True)
class User:
id: str
name: str
is_active: bool = True
@dataclass(不可变用 frozen=True)或 NamedTuple,不用裸 dict/tuple 传递field(default_factory=...),不用裸 []/{}__slots__ 降内存(也防止意外加属性)PEP 8 的命名与导入是 Python 的语言特化规则(不是通用 clean-code):
# ❌ 通配导入污染命名空间、遮蔽名字、破坏静态分析
from os.path import *
# ✅ 显式导入;顺序:标准库 → 第三方 → 本地,各组间空行
import json
from pathlib import Path
import requests
from mypackage.models import User
from module import *(__init__.py 的受控 re-export 除外,且配 __all__)snake_case(函数/变量/模块)、PascalCase(类)、UPPER_SNAKE_CASE(常量)isort/ruff 自动维护;不在函数内部隐藏顶层依赖(循环依赖除外,且注明)GIL 决定了选型:选错模型 = 白忙:
# ❌ 在 async 协程里做阻塞调用,阻塞整个事件循环
async def handler():
data = requests.get(url).text # 同步阻塞
# ✅ async 路径全程 await 非阻塞 IO
async def handler():
async with aiohttp.ClientSession() as s, s.get(url) as r:
data = await r.text()
asyncio 或 ThreadPoolExecutor;CPU 密集:ProcessPoolExecutor/多进程(线程受 GIL 限制无法并行算)async 函数里调用同步阻塞 IO;阻塞调用放线程池(loop.run_in_executor)concurrent.futures 收集结果时处理每个 future 的异常black(或 ruff format);导入:isort / ruff;行宽随项目(默认 88)ruff check(含 pyflakes/pycodestyle/isort 规则集);类型:mypy(趋向 --strict,至少 disallow_untyped_defs);安全:bandit、依赖 pip-audit# noqa: CODE 理由 / # type: ignore[code]),"历史就有"不豁免本次触碰的文件pytest(+ pytest-cov);fixture 管理资源,参数化覆盖边界;无隐藏 time.sleeppyproject.toml([tool.ruff]/[tool.mypy]/[tool.pytest.ini_options])Any 逃避;mypy 通过except / except: pass;包装异常用 from;捕获具体类型with;自定义资源实现上下文管理协议is 仅用于 None/单例;值比较用 ==;类型判定用 isinstancedefault_factoryimport *;命名符合 PEP 8;导入分组有序