with one click
python-idioms
写 Python 时使用。地道、安全、可维护的 Python 写法。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
写 Python 时使用。地道、安全、可维护的 Python 写法。
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
做 Cocos Creator 多机型/多分辨率适配时使用。Canvas、Widget、安全区。
Cocos Creator 用 AssetBundle 做分包/远程资源时使用。加载、释放、依赖、缓存。
优化 Cocos Creator 渲染性能时使用。合批、图集、动静分离、Label。
给 Cocos Creator 原生包做热更新时使用。version manifest、增量、校验、回滚。
写 Cocos Creator 动效/动画时使用。tween、Animation、Spine、性能与清理。
做 Cocos Creator 大量条目列表时使用。虚拟列表、节点复用。
| name | python-idioms |
| description | 写 Python 时使用。地道、安全、可维护的 Python 写法。 |
| category | language |
| tags | ["python","惯用法"] |
except 时。规则: 优先使用列表/字典/集合推导式、enumerate、zip、生成器表达式;凡是靠下标手动累加的循环,基本都有更地道的写法。
为什么: AI 生成 Python 代码时极容易退化成 Java/C 风格:for i in range(len(arr)): result.append(arr[i] * 2)。这种写法既啰嗦又容易因下标越界出 bug,而且完全没有利用 Python 的高阶抽象。读者一眼扫过去就知道这段代码不是"Python 人"写的。
怎么做:
enumerate(seq),不要 range(len(seq))。zip(a, b),不要双重下标。map/filter/itertools,但可读性优先于炫技。规则: 能用标准库解决的不造轮子;所有公开函数加类型注解;函数只做一件事;默认参数值若是可变对象(list/dict/set)必须用 None 代替。
为什么: AI 常见错误之一是把可变对象直接当默认参数:def add_item(item, bucket=[]):——这个 bucket 在所有调用间共享,函数第二次调用时里面已经有上次留下的数据,是 Python 最经典的"幽灵 bug"。类型注解则让 mypy 在运行前就能发现大量错误。
怎么做:
param: list | None = None,函数体内 if param is None: param = []。collections.defaultdict、pathlib.Path、dataclasses.dataclass 代替手写字典嵌套、字符串拼路径、裸 __init__。X | Y)和 PEP 585(list[int]),Python 3.10+ 不再需要从 typing 导入基础类型。with;不裸 except规则: 捕获异常时必须指定类型(except ValueError),禁止裸 except: 或 except Exception as e: pass;打开文件、网络连接、数据库游标等资源必须用 with 语句管理。
为什么: 裸 except 会吞掉 KeyboardInterrupt、SystemExit 等非异常信号,导致程序无法正常终止;同时把真正的 bug 掩盖掉,让问题在更下游以更难理解的形式爆发。AI 在不确定异常类型时倾向于写 except Exception,这是懒惰的防御,不是可靠的错误处理。
怎么做:
except,必要时记录日志后重新 raise。except Exception as e: logger.error(...); raise —— 记录后重抛,不静默吞掉。close() 的对象 → with 语句;若对象不支持上下文管理器,用 contextlib.closing 包装。规则: 项目必须有虚拟环境(venv/poetry/uv);依赖版本必须锁定(requirements.txt 精确版本或 poetry.lock);代码风格服从 PEP 8,同时与项目已有风格保持一致,不随意引入新的格式规则。
为什么: AI 常见问题:在系统 Python 环境下直接 pip install,或者在 requirements.txt 里写 requests>=2.0(范围依赖),导致不同机器的依赖版本不同,代码在 CI 上跑通在生产上崩。另一类问题是在只用单引号的项目里突然改成双引号,污染 git blame,引起不必要的 review 争议。
怎么做:
python -m venv .venv,或用 uv init;提交 requirements.txt(pip freeze > requirements.txt)或 poetry.lock。ruff/black 统一,CI 跑检查;不手动与 formatter 对抗。pyproject.toml/setup.cfg 了解风格约定,再动手。规则: 去重用 set,成员判断用 set/dict(O(1)),建模用 dataclass/NamedTuple,配置聚合用类而非散落的模块级变量;不用全局变量传递运行时状态。
为什么: AI 最常见的性能 bug:用 list 做成员判断——if item in big_list——在列表有几万条时变成 O(n) 查找,线上表现与本地测试差几个数量级。另一类错误是把运行时状态(当前用户、请求上下文)塞进模块全局变量,多线程/异步场景下造成竞态。
怎么做:
set 或 dict。@dataclass,不要裸 dict(键名不受类型检查保护)。contextvars.ContextVar。# 反例 — 下标循环、裸 except、可变默认参数、无类型注解
def process(items, result=[]): # ❌ 可变默认参数,调用间共享
for i in range(len(items)): # ❌ C 风格,应用 enumerate
try:
result.append(items[i].strip().upper())
except: # ❌ 裸 except,吞掉所有异常
pass
return result
# 正例 — 地道 Python
from __future__ import annotations
def process(items: list[str], result: list[str] | None = None) -> list[str]:
if result is None: # ✅ 安全默认参数
result = []
for item in items: # ✅ 直接迭代,无下标
try:
result.append(item.strip().upper())
except AttributeError as e: # ✅ 具体异常类型
raise ValueError(f"期望字符串,得到 {type(item)}") from e
return result
# 反例 — O(n) 成员查询,数据量大时极慢
BLOCKED_USERS = ["alice", "bob", "charlie", ...] # 假设有几万条
def is_blocked(username: str) -> bool:
return username in BLOCKED_USERS # ❌ list.__contains__ 是 O(n)
# 正例 — O(1) 查询
BLOCKED_USERS: set[str] = {"alice", "bob", "charlie", ...} # ✅ set
def is_blocked(username: str) -> bool:
return username in BLOCKED_USERS # ✅ set.__contains__ 是 O(1)
for i in range(len(...))?能否换成 enumerate 或直接迭代?list/dict/set 直接作为默认值)?except 是否指定了具体异常类型,没有静默吞掉错误?with 语句管理?set/dict 而非 list?