上下文管理协议
上下文管理协议,即with语句。为了让一个对象兼容with语句,必须要在这个对象的类中声明__enter__和__exit__方法
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') #with触发__enter__,返回值赋值给f,执行完with语句后触发__exit__ with Open('a.txt') as f: print(f) print('123') #result: # 执行enter # <__main__.Open object at 0x005FF950> # 执行exit # 123
1.with obj-------->触发obj.__enter__(),拿到返回值
2.as f---------->f=返回值
3.执行代码块;
一、没有异常:整个代码块运行完毕后触发__exit__,它的三个参数都为None
二、有异常:从异常出现的位置直接触发__exit__
a.如果__exit__的返回值为True,代表吞掉了异常
b.如果__exit__的返回值不为True,代表吐出了异常,后面的代码都不会运行
c.__exit__的运行完毕就代表了整个with语句的执行完毕
class Open(): def __init__(self,name): self.name=name def __enter__(self): print('执行enter') return self #当with语句异常时,才会有报错信息,参数才有值 def __exit__(self, exc_type, exc_val, exc_tb): print('执行exit') print(exc_type) print(exc_val) print(exc_tb) return True #----------------------------------------- # #with触发__enter__,返回值赋值给f,执行完with语句后触发__exit__ # with Open('a.txt') as f: # print(f) # # #result: # # 执行enter # # <__main__.Open object at 0x0066FFB0> # # 执行exit # # None # # None # # None # #--------------------------------------------- #执行完__exit__,不会继续向下执行 with Open('a.txt') as f: print(f) print(asdfsdgd) print(f.name) # # #result: # # 执行enter # # Traceback (most recent call last): # # <__main__.Open object at 0x00BFFFB0> # # File "D:/Programs/Python/Python37-32/untitled1/day21/time.py", line 29, in <module> # # 执行exit # # <class 'NameError'> #exc_type # # name 'asdfsdgd' is not defined #exc_val # # <traceback object at 0x00CA56C0> #exc_tb # # print(asdfsdgd) # # NameError: name 'asdfsdgd' is not defined #------------------------------------------------------------- #在__exit__加上return True:把异常吞了 , 跳出with语句,继续向下执行 #result: # 执行enter # <__main__.Open object at 0x00D0FFB0> # 执行exit # <class 'NameError'> # name 'asdfsdgd' is not defined # <traceback object at 0x00DA6698>