Python contextlib 模块
contextlib 模块提供工具简化上下文管理器的创建,无需定义完整的类。
contextmanager 装饰器
将生成器函数转换为上下文管理器,yield 之前的代码对应 __enter__,之后的代码对应 __exit__。
Python
from contextlib import contextmanager
@contextmanager
def open_file(filename, mode='r'):
f = open(filename, mode)
try:
yield f # __enter__ 返回值
finally:
f.close() # __exit__ 清理代码
with open_file('test.txt', 'w') as f:
f.write('Hello')
异常处理
Python
@contextmanager
def safe_operation():
print("开始操作")
try:
yield
except Exception as e:
print(f"捕获异常: {e}")
raise # 重新抛出异常
finally:
print("清理资源")
with safe_operation():
raise ValueError("测试异常")
closing 函数
自动调用对象的 close 方法。
Python
from contextlib import closing
from urllib.request import urlopen
with closing(urlopen('http://example.com')) as page:
content = page.read()
# 自动调用 page.close()
suppress 函数
抑制指定的异常类型。
Python
from contextlib import suppress
# 抑制 FileNotFoundError
with suppress(FileNotFoundError):
os.remove('nonexistent.txt') # 文件不存在也不报错
# 等价于
try:
os.remove('nonexistent.txt')
except FileNotFoundError:
pass
redirect_stdout / redirect_stderr
重定向标准输出和标准错误。
Python
from contextlib import redirect_stdout
import io
f = io.StringIO()
with redirect_stdout(f):
print("Hello") # 输出到 f 而非控制台
output = f.getvalue() # "Hello\n"
ExitStack
动态管理多个上下文管理器。
Python
from contextlib import ExitStack
filenames = ['a.txt', 'b.txt', 'c.txt']
with ExitStack() as stack:
files = [stack.enter_context(open(fname)) for fname in filenames]
# 使用所有文件
for f in files:
print(f.read())
# 所有文件自动关闭
常用工具对比
| 工具 | 用途 |
|---|---|
| contextmanager | 用生成器创建上下文管理器 |
| closing | 自动调用 close 方法 |
| suppress | 抑制指定异常 |
| redirect_stdout | 重定向标准输出 |
| redirect_stderr | 重定向标准错误 |
| ExitStack | 动态管理多个上下文 |
要点总结
@contextmanager装饰器用生成器简化上下文管理器创建- yield 之前是
__enter__,yield 之后是__exit__ closing自动调用对象的 close 方法suppress简化异常抑制代码ExitStack适合动态数量的资源管理- contextlib 是资源管理的实用工具集
📝 发现内容有误?点击此处直接编辑