上下文管理协议
上下文管理协议用于规定实现该协议的某个对象(这个对象是上下文管理器__enter__()方法的返回值)的使用范围。什么意思呢?就是一旦开始操作这个对象或者要结束对这个对象的操作,由于这个对象受到上下文管理器管理,会自动进行内存分配或者释放内存、捕捉异常等等,而无需手动管理
一个类实现了__enter__()和__exit__()方法,就说这个类遵守上下文管理协议;而这个类的对象就叫上下文管理器
上下文管理器
上下文管理器,ContextManager,是Python编程中的重要概念,是实现了上下文管理协议的类的实例对象
注意:上下文管理器,管的是自己的__enter__()方法返回的那个对象,能够让那个对象在程序执行过程中可以自动获得内存、释放内存、捕获异常等等
例子:
我们通常会用 try ... catch ... finally 语句确保一些系统资源得以正确释放如:
try:
f = open('file')
for line in f.read():
print(line)
except Exception as e:
print(e)
finally:
f.close()
这样写相对麻烦,需要手动关闭文件和捕捉异常。而我们知道,上下文管理器可以全自动的,不用手动关不用管异常,美滋滋,于是我们尝试用上下文管理器实现这样的操作:
with open('file') as f:
for line in f.read():
print(line)
可以看到,完全不用管异常和最后关闭文件,只需要专注于要做的事本身
with 语句到底干了什么
with只能配合上下文管理器使用,那么with语句是如何执行的?
第一步:执行上下文表达式,生成上下文管理器对象。上下文表达式就是 with 和 as 之间的代码
第二步:加载但不执行上下文管理器对象的 __exit__()方法(这步不太重要)
第三步:执行上下文管理器对象的__enter__()方法
第四步:将__enter__()方法返回值赋值给 as 后面的变量
第五步:执行 with 内的代码块
第六步:执行上下文管理器的__exit__()方法
例子:
class Sample:
def __enter__(self):
print ("执行enter方法,返回被管理的对象")
#返回被管理的对象,这里是self,当然也可以是其他类的对象
return self
def __exit__(self, exc_type, exc_val, exc_tb):
#释放资源
print ("执行exit释放资源")
def doSomething(self):
print ("doing something")
with Sample() as sample:
sample.doSomething()
执行结果如下:
执行enter方法,返回被管理的对象
doing something
执行exit释放资源
