Python contextlib
学习contextmanager · 难度:高级 · +15XP
Python contextlib 上下文管理
contextlib 是 Python 标准库中用于简化上下文管理器创建的模块。上下文管理器最常用的形式是 with 语句,它能确保资源在使用后被正确释放(如文件关闭、锁释放、数据库连接断开等)。contextlib 提供了便捷的方式来定义和管理上下文。
@contextmanager 装饰器
使用 @contextmanager 可以将一个生成器函数转换为上下文管理器,比实现 __enter__ 和 __exit__ 方法更简洁:
from contextlib import contextmanager
@contextmanager
def file_manager(filename, mode):
print('打开文件')
f = open(filename, mode)
try:
yield f # 将资源交给 with 块
finally:
print('关闭文件')
f.close()
# 使用
with file_manager('test.txt', 'w') as f:
f.write('Hello World')
# 输出: 打开文件 / 关闭文件
常用 contextlib 工具
from contextlib import closing, suppress, redirect_stdout
import io, os
# closing - 确保对象被关闭
from urllib.request import urlopen
with closing(urlopen('https://www.python.org')) as page:
content = page.read()
# suppress - 忽略指定的异常
with suppress(FileNotFoundError):
os.remove('nonexistent.txt') # 文件不存在也不报错
# redirect_stdout - 重定向标准输出
buffer = io.StringIO()
with redirect_stdout(buffer):
print('Hello')
print('World')
output = buffer.getvalue()
print(output) # Hello
World
ExitStack - 动态管理多个上下文
from contextlib import ExitStack
def process_files(filenames):
with ExitStack() as stack:
# 动态打开多个文件
files = [
stack.enter_context(open(fname))
for fname in filenames
]
# 同时处理所有文件
for f in files:
print(f.readline().strip())
# 退出时自动关闭所有文件
process_files(['a.txt', 'b.txt', 'c.txt'])
contextlib 工具速查表
| 工具 | 说明 |
|---|---|
| @contextmanager | 将生成器函数转为上下文管理器 |
| closing(obj) | 确保对象在退出时调用 .close() |
| suppress(*exc) | 忽略指定类型的异常 |
| redirect_stdout(f) | 将 stdout 重定向到文件对象 |
| redirect_stderr(f) | 将 stderr 重定向到文件对象 |
| nullcontext() | 不执行任何操作的上下文管理器 |
| ExitStack | 动态组合多个上下文管理器 |