python中的with和上下文管理器 2019-10-12(未经允许禁止转载)

上下文管理协议

上下文管理协议用于规定实现该协议的某个对象(这个对象是上下文管理器__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释放资源
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容