其他
用上下文管理器确定性管理 Python 资源(连接…
在管理数据库连接/连接池、文件句柄与 I/O、自定义清理逻辑、带累积状态的流式响应或嵌套资源清理时,用 with / async with 与上下文管理器协议保证资源必定释放。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 48/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 54/100 ×0.15
适用场景
用上下文管理器确定性管理 Python 通用
解决思路
- 用 `with` 语句包裹资源使用,让资源在异常发生时也能自动释放。
- 同步资源实现 `__enter__`/`__exit__`,异步资源实现 `__aenter__`/`__aexit__`。
- 把清理逻辑放在 `__exit__` 中无条件执行(无论是否发生异常都会运行)。
- `__exit__` 返回 `True` 表示抑制异常,返回 `False`/`None` 表示继续向上传播异常。
- 简单场景用 `@contextmanager`:在 `try:` 中 `yield resource`,在 `finally:` 中调用 `resource.cleanup()`,然后 `with managed_resource() as r: r.do_work()`。
- 复杂资源用类实现上下文管理器协议:`__enter__` 中调用 `connect()` 建立连接并 `return self`;`__exit__` 中调用 `close()` 关闭连接并把连接字段置为 `None`(先判断不为 None)。
- 同时支持 with 和手动管理两种用法:`with DatabaseConnection(dsn) as db: db.execute(query)`;需要手动时用 `db = ...; db.connect(); try: ... finally: db.close()`。
- 异步连接池:`__aenter__` 中 `await asyncpg.create_pool(dsn, min_size=..., max_size=...)` 并返回 self;`__aexit__` 中 `await self._pool.close()`;执行查询时用 `async with self._pool.acquire() as conn: return await conn.fetch(query, *args)`。
- 用 `@asynccontextmanager` 管理数据库事务:先 `await conn.execute("BEGIN")`,`yield conn` 后 `await conn.execute("COMMIT")`;捕获 `Exception` 时 `await conn.execute("ROLLBACK")` 并 `raise` 重新抛出。
- 用 `@contextmanager` 实现计时/日志块:`start = time.perf_counter()`,`yield`,在 `finally` 中计算 `elapsed` 并记录日志(如 `duration_seconds=round(elapsed, 3)`)。
- 在 `__exit__` 中做无条件清理:关闭主文件句柄;遍历 `self._temp_files` 逐个 `temp_file.unlink()`,并用 `try/except OSError: pass` 做尽力而为的清理。
- 不要在 `__exit__` 中意外抑制异常——除非有意抑制,否则返回 `False`/`None` 让异常传播。
- 当资源数量动态不定时,使用 `ExitStack` 来管理。
- 累积数据时用 list 收集再 `join`,不要用字符串拼接。
- 为流式响应记录指标,尤其是 time-to-first-byte。
- 为上下文管理器编写文档,特别说明它是否会抑制异常。
- 测试清理路径,验证出错时资源确实被释放。
- 当导航摘要信息不足时,阅读 `references/details.md` 中 `## Advanced Patterns` 起的高级模式细节。
- 对任何需要清理的资源都优先使用上下文管理器。