原文链接:https://www.cnblogs.com/Meanwey/p/9898673.html
即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法
class Open: def __init__(self,name): self.name = name def __enter__(self): #在实例化打开文件时即触发,在with时触发 print('执行__enter__') return self #return的self会赋值给f,相当于通过Open类实例化处对象f def __exit__(self,exc_type,exc_val,exc_tb): #在with中的代码块执行完毕才会触发 print('执行__exit__') with Open('a.txt') as f: #会触发enter '执行__enter__',相当于--》f=Open('a.txt').__enter__() print(f) #<__main__.Open object at 0x01477270> print(f.name) #'a.txt' print('*'*10) #先---'执行__exit__' #后---'*********' Output: --------------------------------------------- 执行__enter__ <__main__.Open object at 0x000000000210B208> a.txt 执行__exit__ ********** ---------------------------------------------
__exit__()中有三个参数分别代表异常类型,异常值和追溯信息,执行了__exit__则表示with语句执行完毕 1、若__exit__返回值不为True,则: a、若with语句中没有异常,则程序正常执行 b、若with语句中出现异常,则程序会执行到with中出错的语句并执行__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__') print(exc_type) #<class 'AttributeError'> print(exc_val) #'Open' object has no attribute 'age' print(exc_tb) #<traceback object at 0x0178F738> with Open('a.txt') as f: print(f) print(f.age) #因为f对象没有age属性,则出现异常,程序执行到该句时将异常传递给__exit__的三个参数,并结束程序执行,报错 print(f.name) #该行语句后面的语句都不会执行,包括with语句的以外的语句也不会执行 print('*'*10) Output: --------------------------------------------------------- 执行__enter__ print(f.age) AttributeError: 'Open' object has no attribute 'age' <__main__.Open object at 0x000000000257E4A8> 执行__exit__ <class 'AttributeError'> 'Open' object has no attribute 'age' <traceback object at 0x0000000002583288> ---------------------------------------------------------
2、若__exit__返回值为True,则: a、若with语句中没有异常,则程序正常执行 b、若with语句中出现异常,则程序会执行到with中出错的语句并执行__exit__,‘吞掉’异常。然后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) #<class 'AttributeError'> print(exc_val) #'Open' object has no attribute 'age' print(exc_tb) #<traceback object at 0x0178F738> return True with Open('a.txt') as f: print(f) print(f.age) #因为f对象没有age属性,则出现异常,程序执行到该句时将异常传递给__exit__的三个参数,并结束程序执行,'吞掉异常'不会报错 print(f.name) #该行语句后面的with中的语句都不会执行,但是with语句的以外的语句会继续执行 print('*'*10) #'*********'
1.使用with语句的目的就是把代码块放入with中执行,with结束后,自动完成清理工作,无须手动干预 2.在需要管理一些资源比如文件,网络连接和锁的编程环境中,可以在__exit__中定制自动释放资源的机制,你无须再去关系这个问题,这将大有用处
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句