要使用 with 语句,首先要明白上下文管理器这一概念。有了上下文管理器,with 语句才能工作。

上下文管理协议(Context Management Protocol):包含方法 __enter__() __exit__(),支持该协议的对象要实现这两个方法。

上下文管理器(Context Manager):支持上下文管理协议的对象,这种对象实现了
__enter__() __exit__()方法。上下文管理器定义执行 with 语句时要建立的运行时上下文,负责执行 with 语句块上下文中的进入与退出操作。通常使用 with 语句调用上下文管理器,也可以通过直接调用其方法来使用。说白了就是你只要是包含了__enter__() __exit__()这两个魔法函数,我就可以把你当做一个上下文管理器(鸭子类型)来操作。

我们先来看一段代码,给这个函数实现上下文管理协议:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Sample:
def __enter__(self):
# 获取资源
print("enter")
return self

def __exit__(self, exc_type, exc_val, exc_tb):
# 释放资源
print("exit")

def doSomething(self):
print(" I am doingsomething")

sample = Sample()
sample.doSomething()

# 输出结果:
I am doingsomething

这是按照我们正常的实例化对象的操作,但是我们还没有调用因魔法函数而增强的功能,如何调用呢?使用with语句就可以了:

1
2
3
4
5
6
7
8
with Sample() as sample:
sample.doSomething()

# 输出结果:
enter
I am doingsomething
exit

看到没有,这里我们其实也是实例化了Sample的对象,不过是使用with来完成的,然后它就自动调用了我们2个魔法函数。不知道你注意没有,这个I am doingsomething是在中间输出的,你可能会问为啥不是最后呢?(按照调用的顺序就应该是这样啊)其实不是的,因为你前面虽说是获取了资源,但是你所获取的资源并没有完全加载完,然后就去释放资源啊,所以肯定就是这样了。

参考文章:浅谈 Python 的 with 语句