本文实例讲述了Python与语句上下文管理器。分享给大家供大家参考,具体如下:
在编程中会经常碰到这种情况:有一个特殊的语句块,在执行这个语句块之前需要先执行一些准备动作,当语句块执行完成后,需要继续执行一些收尾动作,例如,文件读写后需要关闭,数据库读写完毕需要关闭连接,资源的加锁和解锁等情况。
对于这种情况python提供了上下文管理器(上下文管理器)的概念,可以通过上下文管理器来定义/控制代码块执行前的准备动作,以及执行后的收尾动作。
<强> 1,不使用上下文管理器的情况强>
通过试…最后语句执行异常处理和关闭句柄的动作。
(“日志记录器=开放。txt”、“w”) 试一试: 记录器。写(“你好”) logger.write(世界) 最后: logger.close () 打印logger.closed >之前<强> 2,使用上下文管理器强>
默认文件Python的内置文件类型是支持上下文管理协议的。
使用上下文管理器,使得依据精简了很多。张开(“日志。记录器txt”、“w”): 记录器。写(“你好”) logger.write(世界) 打印logger.closed >之前方法一:类实现__enter__和__exit__方法。方法二:contextlib模块装饰器和生成器实现。
下面我们通过两种方法分别实现一个自定义的上下文管理器。
<强> 1,方法一:通过类实现__enter__和__exit__方法强>
类文件(对象): def __init__(自我、file_name方法): 自我。file_obj=开放(file_name、方法) def __enter__(自我): 返回self.file_obj def __exit__(自我、类型值,回溯): self.file_obj.close () 与文件(“演示。opened_file txt”、“w”): opened_file.write(“你好!”) >之前实现__enter__和__exit__方法后,就能通过与语句进行上下文管理。
,底层都发生了什么?
1,语句先暂存了文件类的__exit__方法,然后它调用文件类的__enter__方法。
2,__enter__方法打开文件并返回给与语句,打开的文件句柄被传递给opened_file参数。
3,与语句调用之前暂存的__exit__方法,__exit__方法关闭了文件。b,异常处理
关于异常处理,与语句会采取哪些步骤。
1。它把异常的类型、价值和回溯传递给__exit__方法
2. 它让__exit__方法来处理异常
3.如果__exit__返回的是真的,那么这个异常就被忽略。
4. 如果__exit__返回的是真正以外的任何东西,那么这个异常将被与语句抛出。<强>异常抛出强>
#异常抛出,_exit__返回的是真正以外的任何东西,那么这个异常将被与语句抛出 类文件(对象): def __init__(自我、file_name方法): 自我。file_obj=开放(file_name、方法) def __enter__(自我): 返回self.file_obj def __exit__(自我、类型值,回溯): self.file_obj.close () 打印“类型:”类型 打印”价值:”价值 打印“回溯:”,回溯 与文件(“演示。opened_file txt”、“w”): opened_file.undefined_function(“你好!”) #输出================================================#类型:& lt;类型exceptions.AttributeError的祝辞 #价值:‘文件’对象没有属性“undefined_function” #回溯:& lt;回溯在0 x000000000262d9c8>对象; # opened_file.undefined_function(“你好!”) # AttributeError:‘文件’对象没有属性“undefined_function” >之前<强>异常忽略:强>
#异常忽略,__exit__返回的是真的,那么这个异常就被忽略。 类文件(对象): def __init__(自我、file_name方法): 自我。file_obj=开放(file_name、方法) def __enter__(自我): 返回self.file_obj def __exit__(自我、exception_type exception_value回溯): print(“异常得到处理”) self.file_obj.close () 还真 与文件(“演示。opened_file txt”、“w”): opened_file.undefined_function(“你好!”) #输出==================================#异常处理 >之前<强> 2,方法二:contextlib模块装饰器和生成器实现强>
这种方式实现更优雅,我个人更喜欢这种方式。
Python与语句上下文管理器两种实现方法分析