在Python里,上下文管理器类是一种用来配合with语句自动管理资源的对象。通过自己写一个类,并在里面实现特定方法,就能控制代码块执行前后发生的事情,比如打开关闭文件、加锁解锁等。

什么是上下文管理器类
上下文管理器类就是实现了__enter__和__exit__方法的普通类。当这个类实例被用在with语句中时,Python会自动调用这两个方法。
核心方法说明
- __enter__(self):进入with块时调用,它的返回值会赋给as后面的变量。
- __exit__(self, exc_type, exc_val, exc_tb):离开with块时调用,三个参数分别对应异常类型、异常值和追踪信息。如果一切正常它们为None。
如何定义一个简单的上下文管理器类
下面写一个管理文件读写的类,进入时打开文件,退出时关闭文件。
class FileManager:
def __init__(self, filename, mode):
# 保存文件名和打开模式
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
# 进入时打开文件并返回文件对象
self.file = open(self.filename, self.mode, encoding='utf-8')
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
# 退出时关闭文件
if self.file:
self.file.close()
# 返回False表示不吞掉异常
return False
# 使用自定义上下文管理器
with FileManager('test.txt', 'w') as f:
f.write('hello context manager')
处理异常的情况
在__exit__方法中,我们可以根据异常参数决定是否处理异常。如果方法返回True,则with块中的异常不会被向外抛出。
class SafeRunner:
def __enter__(self):
print('开始执行')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type is not None:
print('捕获到异常:', exc_val)
# 返回True吞掉异常
return True
with SafeRunner():
raise ValueError('出错了')
print('程序继续运行')
使用contextlib简化定义
如果不想写完整的类,也可以用标准库中的contextlib.contextmanager装饰器,通过生成器函数快速实现。但掌握类的定义方式,有助于理解底层机制。
| 方式 | 适用场景 |
|---|---|
| 定义类 | 逻辑复杂、需要保存状态 |
| 装饰器 | 简单的一次性资源管理 |
小结
定义上下文管理器类只需实现__enter__和__exit__两个方法,再配合with语句即可安全管理资源。实际开发中应根据需求选择类或装饰器方案。