26. 上下文管理
一、什么是上下文管理器
任何实现 __enter__()
和 __exit__()
方法的对象都可称为 上下文管理器。上下文管理器对象可以使用 with 关键字。这样说的话,文件(file)对象也实现了上下文管理器。
__enter__()
方法返回资源对象,这里就是你将要打开的那个文件对象,__exit__()
方法处理一些清除工作。
class File:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def __enter__(self):
print("__enter__()方法执行了!")
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, *args):
print("__exit__()方法执行了!")
self.file.close()
现在,File 类实现了上下文管理器,可以使用 with 语句了。
with File("text.txt", "w") as f:
print("writing...")
f.write("hello world!")
这样就无需显示地调用 close() 方法了,由系统自动调用,哪怕中间出现异常,close() 方法也会被调用。
我们也可以使用 @contextmanager 装饰器实现上下文管理器。
from contextlib import contextmanager
@contextmanager
def my_open(path, mode):
f = open(path, mode)
yield f
f.close()
with my_open("text.txt", "w") as f:
print("writing...")
f.write("hello, this is a simple context manager!")
之所以使用上下文管理器,是因为在开发过程中一般都会使用系统资源(文件、网络、设备等),此时我们在使用完毕之后一定要关闭。一般关闭使用 xxx.close() 方法,但是这种方式在产生异常的情况下不会被自动调用,即可能出现资源没有被正确的关闭,这会导致系统资源一直占用。因此,我们需要使用更简单,但是更有效的方式,即 with 来使用。
上下文管理器,简单的来说分为 2 部分,一部分是申请资源,另外一部分是释放资源,而在 with 中使用资源,with 会自动调用申请资源以及释放资源的代码。