上下文管理是资源释放的首选方式,因其能确保无论是否异常,__exit__ 都会被执行,从而可靠释放文件句柄、网络连接等有限资源;标准库中多数资源类已内置支持,如文件、数据库连接、线程锁;自定义可用 @contextmanager 简化实现;需避免对非上下文对象使用 with 或不当抑制异常。

为什么上下文管理是资源释放的首选方式
手动调用 close() 或 __del__ 容易遗漏、出错,尤其在异常发生时资源可能永远不被释放。上下文管理器(with 语句)能确保无论是否异常,__exit__ 都会被执行,从而可靠释放文件句柄、网络连接、数据库游标、锁等有限资源。
用 with 管理常见资源:文件、数据库、锁
标准库中多数资源类已内置上下文支持,直接使用即可:
-
文件操作:
with open('data.txt') as f: content = f.read()—— 自动关闭,无需f.close() -
数据库连接(如 sqlite3):
with conn: cursor = conn.cursor()—— 自动提交或回滚事务;若需显式控制,可用with conn: ...或封装为自定义上下文管理器 -
线程锁:
with lock: shared_data += 1—— 避免忘记release()导致死锁
自定义上下文管理器:@contextmanager 更简洁
无需写完整类,用 contextlib.contextmanager 装饰生成器函数即可:
<font size="2">from contextlib import contextmanager <p>@contextmanager def temporary_file(suffix='.tmp'): import tempfile fd, path = tempfile.mkstemp(suffix=suffix) try: yield path # 进入 with 块时返回 finally: import os os.unlink(path) # 退出时必然执行,释放临时文件</font>
关键点:yield 前的代码相当于 __enter__,finally 块对应 __exit__,天然支持异常安全清理。
立即学习“Python免费学习笔记(深入)”;
避免常见陷阱:嵌套、异常抑制与非资源对象
注意以下易错点:
- 不要对非上下文对象(如普通函数返回值、未实现 __enter__/__exit__ 的类实例)强行用 with,会报 AttributeError
- 嵌套多个 with 时,退出顺序与进入顺序相反(后进先出),确保依赖关系正确(如先开文件再连数据库,应先关数据库再关文件)
- 除非明确需要,不要在 __exit__ 中返回 True 抑制异常——这会掩盖真实错误,不利于调试










