一.使用场景 我们经常在进行文件操作时使用with语句来进行操作,这就关系到了上下文管理协议了。 二.使用 在使用with语句时,我们用到了__enter__()和__exit__()方法来进行文件的操作。如下图所示,我们可以自定义一个类似with功能的类来实现该功能。 我们可以发现,with Open() as f,可以看做是,就行了一个实例化的过程,它是先执行,enter()方法,再执行with代码块,最后执行了__exit__()函数,接着才会执行with之后的代码块。 问题1:with代码块中没有异常的情况 没有异常的情况下,直接先Open()进行一个实例化,首先执行__enter()方法,并将返回值赋值给f,再执行with代码块,接着是执行__eixt()方法,最后是执行with之后的代码块。如下图所示: __exit__()方法中参数说明: exc_type:异常类; exc_val,:异常的值; exc_tb:异常的追踪信息。 问题2.with代码块中有异常 1.系统内部对异常未做任何处理 如果with中出现了异常,代码会怎样运行呢?见下图: With语句前面部分执行__enter()方法不变,接着执行with内部的代码块,其中如果有异常,则在发生异常出直接运行__exit()方法,若_exit__()方法返回值不为Ture,则并停止整个程序的运行(因为程序遇到了问题,不再往下运行了) 2.系统内部处理了异常 With语句前面部分执行__enter__()方法不变,接着执行with内部的代码块,其中如果有异常,则在发生异常处直接运行__exit__()方法,若_exit__()方法返回值为Ture,则结束with内部代码,接着执行with之外(之后)的代码块,如下图: 该部分的代码块如下:

class Open():
    def __init__(self,name):
        self.name = name
    def __enter__(self):
        print('执行__enter__()方法')
        return  self
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('执行__exit__方法')
        print(exc_type)
        print(exc_val)
        print(exc_tb)
        return  True
with Open('W.txt') as f:
    print("执行with代码块")
    print(f.name)
    print(f.value)  #--->错误在此处
    print("执行with最后的代码块")   #--->不执行
print("继续with之后的代码块")

三.有何用途? 1.使用with语句的目的是将代码块放入with中执行,with结束后,会自动完成清理工作(内存清理),无需手动干预。 也就是说,在with结束后会自动关闭文件(使用close方法),我们可以想到,不管有没有异常,with代码块最后都会执行__exit__()方法,此时我们可以在__exit__()中完成内存清理工作。 2.在需要管理一些资源如文件、网络连接和锁等编程环境中,我们可以在__exit__方法中自定义释放资源的机制。该功能会有很大的用处。