除了通过类实现上下文管理器(__enter__ 和 __exit__ 方法),Python 还允许使用 contextlib 模块的 contextmanager 装饰器,通过生成器快速定义上下文管理器。这种方式更简洁,适合简单场景的资源管理。
生成器上下文管理器的原理
使用 @contextmanager 装饰器的生成器函数,需包含一个 yield 语句:
- yield 之前的代码等价于 __enter__ 方法(进入上下文时执行)
- yield 之后的代码等价于 __exit__ 方法(退出上下文时执行,无论是否发生异常)
- yield 的返回值会被 with 语句的 as 子句接收
示例:实现一个简易的文件操作上下文管理器
python
from contextlib import contextmanager
@contextmanager
def file_manager(file_path, mode):
# 等价于 __enter__:获取资源
file = open(file_path, mode)
try:
yield file # 返回资源给 as 子句
finally:
# 等价于 __exit__:释放资源
file.close()
print("文件已关闭")
# 使用上下文管理器
with file_manager("test.txt", "w") as f:
f.write("Hello, context manager!")
上述代码与 open 函数的内置上下文管理器功能一致,但实现更简洁。
应用场景与优势
临时资源管理:如临时文件、数据库连接、网络套接字等,确保使用后自动释放。
@contextmanager
def db_connection():
conn = create_db_connection() # 建立连接
try:
yield conn
finally:
conn.close() # 确保关闭连接
环境变量临时修改:在代码块内临时修改环境变量,退出后自动恢复。
import os
from contextlib import contextmanager
@contextmanager
def temp_env_var(key, value):
original = os.getenv(key) # 保存原始值
os.environ[key] = value
try:
yield
finally:
# 恢复原始值(若不存在则删除)
if original is None:
del os.environ[key]
else:
os.environ[key] = original
代码块计时:统计代码块执行时间,自动处理计时开始与结束。
与类实现相比,生成器上下文管理器的优势在于:代码量少、逻辑清晰,适合无需复杂状态管理的场景。
每天坚持学习一点点,不求有回报,只愿可以丰富自己!!!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
暂无评论...