async-python-patternslisted
Install: claude install-skill sandbaseai/workbuddy-skill
# Async Python Patterns
用 `asyncio` 管理 I/O 并发,同时保持事件循环可响应、资源可回收、取消可传播、并发有上限。异步不是越多越好:CPU 密集任务、低并发脚本或阻塞 SDK 应选择同步、线程池或进程池,并用基线证明收益。
## 使用边界
- 开始前确认 Python/框架/依赖版本、调用链、并发量、deadline、资源配额、owner、SLO 和目标环境。
- 默认只读检查 coroutine、task、连接池、队列、超时、trace 和错误;在本地/预发布使用合成负载与受控故障。
- 不擅自修改生产并发、超时、线程/进程池、连接池、限流、流量或重启服务;这些变更需要授权和回滚方案。
- 日志、task 参数、异常和 trace 不得包含 token、完整 payload、个人信息或原始响应;使用脱敏摘要和受控 correlation ID。
## 同步/异步边界
多网络/数据库调用适合 asyncio;CPU 密集工作使用 `asyncio.to_thread`(阻塞但可释放事件循环)或进程池,并限制 worker。一个调用路径应有清晰的 sync/async 边界,不能在事件循环中执行 `time.sleep`、同步 HTTP/数据库客户端、重型序列化或无界文件操作。
每个外部调用都要有连接、读和总 deadline;每个 task 都说明 owner、结果、异常、取消和资源清理语义。优先使用 `async with`、`async for` 和结构化并发(如 `TaskGroup`,按 Python 版本确认行为)。
```python
import asyncio
async def fetch_bounded(items, client, *, limit=20):
semaphore = asyncio.Semaphore(limit)
async def one(item):
async with semaphore:
# The caller supplies a request deadline; no unbounded await.
return await client.fetch(item, timeout=5.0)
# Keep the result order and make the concurrency bound explicit.
return await asyncio.gather(*(one(item) for item in items))
```
## 并发、背压与结果
`gather`、task 集合、队列和连接池都必须有上限;不要一次为不受控输入创建百万个 task。生产者速度超过消费者时使用 `asyncio.Queue(maxsize=...)`、信号量或流式 `async for`,队列满时暂停、丢弃低优先级或快速失败,并返回明确状态。
决定失败策略:默认一个失败是否取消同组任务、是否收集部分结果、是否允许继续。不要用 `return_exceptions=True` 后静默过滤异常;逐项分类、记录受控上下文并为部分成功定义业务语义。对外部调用结合限流、指数退避+jitter、幂等键和总 deadline,避免并发重试放大。
## 取消、超时与清理
取消是控制流,不应被普通 `except Exception` 吞掉。捕获