13. 上下文管理器
能够用with语句进行管理的对象必须是上下文管理器。
内置的上下文管理器:
- 文件对象
- 线程锁
- 套接字 (socket)
- 子进程 (subprocess)
- 数据库连接 (sqlite3)
- 压缩文件 (gzip, zipfile)
什么是上下文管理器
类内实现了 __enter__
和 __exit__
实例方法的类称为上下文管理器类型,用此类型创建的对象称为上下文管理器。
with 语句在执行时,可以自动调用 __enter__
方法实现资源的申请,在离开with语句时可以自动的调用 __exit__
方法来释放资源,确保资源在使用后被释放。
定义语法
class 上下文管理器类名:
'此类用于创建能够使用with语句进行管理的上下文管理器对象'
def __enter__(self):
'进入with语句时调用,返回资源对象'
return 资源对象(通常是自己)
def __exit__(self, exc_type, exc_value, exc_tb):
'已离开with语句时调用'
__exit__方法的参数说明
- exc_type:绑定异常类型,没有异常时绑定None
- exc_value:绑定异常对象,没有异常时绑定None
- exc_tb:绑定traceBack对象类型,没有异常时绑定None
- traceBack对象可以通过traceback模块的print_tb函数打印出引发异常的位置
- 示例代码
import traceback as tb
tb.print_tb(exc_tb)
示例
# 此示例示意上下文管理器类型的定义方法
class MyContextManager:
def __enter__(self):
print('进入了__enter__方法')
# 此处写申请资源的代码
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('退出了__exit__方法')
print('exc_type:', exc_type)
print('exc_val:', exc_val)
print('exc_tb:', exc_tb)
# 此处写释放资源的代码
if exc_type is not None:
import traceback as tb
tb.print_tb(exc_tb)
print('开始进入with语句!')
with MyContextManager() as obj:
print('with正在执行中')
raise ValueError('myerror!')
print('with语句结束!')
上述自定义的上下文管理器类创建的对象会在进入 with 语句时调用 __enter__
方法。离开时调用 __exit__
方法,并且在离开时能够根据参数知道当前的异常状态等信息。