今天小编给大家分享一下python中的with怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
简介
with的基本表达式如下
with context_expression [as target(s)]: ... with-body
其中context_expression 可以是任意的表达式,as target(s)是可选的
他的执行过程如下
context_manager = context_expressionexit = type(context_manager).__exit__value = type(context_manager).__enter__(context_manager)exc = True # True 表示正常执行,即便有异常也忽略;False 表示重新抛出异常,需要对异常进行处理try: try: target = value # 如果使用了 as 子句 with-body # 执行 with-body except: # 执行过程中有异常发生 exc = False # 如果 __exit__ 返回 True,则异常被忽略;如果返回 False,则重新抛出异常 # 由外层代码对异常进行处理 if not exit(context_manager, *sys.exc_info()): raisefinally: # 正常退出,或者通过 statement-body 中的 break/continue/return 语句退出 # 或者忽略异常退出 if exc: exit(context_manager, None, None, None) # 缺省返回 None,None 在布尔上下文中看做是 False
深入
首先我们来了解两个概念,上下文管理对象与上下文协议
上下文管理器:支持上下文管理协议的对象,这里我们就要知道什么是上下文管理管理协议了,请看第二点。上下文管理器运行with语句是要建立运行的上下文,负责执行with语句块上下文中的进入与退出操作。
上下文管理协议:包含方法__enter__()和__exit__(),支持协议的对象要实现这两个方法
理解完上面的两点,我们就很容易知道with语句的执行流程,我们看着上面的执行过程代码来看
执行context_expression ,生成山下文管理器context_manager
调用上下文管理器的__enter__方法,这个时候如果使用了as,那么就会将__enter__方法的返回值赋值给target
执行with-body
不管执行过程中是否发生了异常都会执行上下文管理器的__exit__方法,它用于负责执行清理工作,如释放资源等。
如果执行过程中没有出现异常,或者语句中执行了语句break/continue/return,则以None作为参数调用__exit__(None,None,None);如果执行过程中出现了异常,则使用sys.excinfo得到异常信息作为参数调用__exit__(exc_type,exc_value,exc_traceback)
出现异常时,如果__exit__(exc_type,exc_value,exc_traceback)返回false,则会重新抛出异常,让with完的语句来处理异常,如果__exit__(exc_type,exc_value,exc_traceback)返回True,则异常忽略,不在对于异常来进行处理
代码
没有报错
class Test: def __enter__(self): print("__enter__") return "hello python" def __exit__(self, type, value, trace): print("__exit__") passdef get_test(): return Test()with get_test() as test: print(test)
他的打印如下
__enter__
hello python
__exit__
有报错
class Test: def __enter__(self): print("__enter__") return "hello python" def __exit__(self, type, value, trace): print("type", type) print("value", value) print("trace", trace) print("__exit__")def get_test(): return Test()with get_test() as test: print(test) 1 / 0
打印如下
hello python
type <class 'ZeroDivisionError'>
value division by zero
trace <traceback object at 0x0000024938B07B40>
__exit__
Traceback (most recent call last):
File "f:/my_profile/study/code_pub/study_code_pub/python/关键字/with.py", line 35, in <module>
1 / 0
可以看出来当有报错的时候,他是抛出了异常,因为__exit__没有返回值,当他返回True的时候,他的打印如下
当__exit__返回True时
__enter__
hello python
type <class 'ZeroDivisionError'>
value division by zero
trace <traceback object at 0x000001FB117885C0>
__exit__
我们会发现他没有了报错信息。
以上就是“python中的with怎么使用”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。