← 返回首页
✅ 推荐(使用
方法 2:使用
🆚 六、
Python中with的使用
在 Python 中,with 语句用于简化资源管理,确保即使在代码执行过程中发生异常,也能自动释放资源(如文件、网络连接、锁等)。它的核心机制是 上下文管理协议(Context Manager Protocol)。
✅ 一、基本语法
with 表达式 as 变量:
# 使用变量的代码块
表达式必须返回一个 上下文管理器对象(实现了__enter__和__exit__方法)变量是__enter__方法的返回值- 无论代码块是否抛出异常,
__exit__都会被调用
📁 二、经典示例:文件操作
❌ 不推荐(手动管理资源)
f = open('file.txt', 'r')
try:
data = f.read()
finally:
f.close() # 必须显式关闭
✅ 推荐(使用 with)
with open('file.txt', 'r') as f:
data = f.read()
# 文件在此自动关闭,即使 read() 抛出异常!
💡 即使发生异常、
return、break,文件也会被正确关闭。
🔧 三、自定义上下文管理器
方法 1:通过类实现
class MyResource:
def __enter__(self):
print("资源已获取")
return self # 返回给 as 后的变量
def __exit__(self, exc_type, exc_val, exc_tb):
print("资源已释放")
# 返回 True 可抑制异常(一般不建议)
return False
# 使用
with MyResource() as res:
print("正在使用资源")
输出:
资源已获取
正在使用资源
资源已释放
方法 2:使用 contextlib 装饰器(更简洁)
from contextlib import contextmanager
@contextmanager
def my_resource():
print("获取资源")
try:
yield "资源对象" # 相当于 __enter__ 的返回值
finally:
print("释放资源")
# 使用
with my_resource() as res:
print(f"使用 {res}")
输出:
获取资源
使用 资源对象
释放资源
🧩 四、常见应用场景
| 场景 | 示例 |
|---|---|
| 文件操作 | with open(...) as f: |
| 线程锁 | with threading.Lock(): |
| 数据库连接 | with connection.cursor() as cur: |
| 临时修改状态 | with decimal.localcontext() as ctx: |
| 测试 mock | with mock.patch('module.func'): |
| 改变工作目录 | 自定义上下文管理器 |
⚠️ 五、重要注意事项
-
__exit__的参数:def __exit__(self, exc_type, exc_val, exc_tb): # exc_type: 异常类型(如 ValueError) # exc_val: 异常实例 # exc_tb: traceback 对象- 如果返回
True,会抑制异常(不抛出) - 通常应返回
False(让异常正常传播)
- 如果返回
-
多个上下文管理器:
with open('in.txt') as fin, open('out.txt', 'w') as fout: fout.write(fin.read())或使用括号(Python 3.1+):
with ( open('in.txt') as fin, open('out.txt', 'w') as fout, ): ... -
as不是必须的:with lock: # 只需执行 __enter__/__exit__,不需要返回值 critical_section()
🆚 六、with vs try/finally
| 特性 | with |
try/finally |
|---|---|---|
| 代码简洁性 | ✅ 高 | ❌ 冗长 |
| 自动资源管理 | ✅ 内置 | ⚠️ 需手动写 |
| 可读性 | ✅ 清晰表达“使用资源”意图 | 一般 |
| 灵活性 | ⚠️ 依赖上下文管理器 | ✅ 完全控制 |
✅ 最佳实践:只要支持上下文管理器,优先用
with
💡 总结
with是 Python 的资源管理利器- 核心价值:自动清理,避免资源泄漏
- 所有支持上下文管理的对象(文件、锁、数据库连接等)都应使用
with - 可通过类或
@contextmanager轻松自定义
🐍 记住:“打开即关闭,使用即安全” —— 这就是
with的哲学。