with EXPR as VAR: BLOCK
其中:EXPR可以是任意表达式;as VAR是可选的。其一般的执行过程是这样的:
- 计算
EXPR,并获取一个上下文管理器。 - 上下文管理器的
__exit()__方法被保存起来用于之后的调用。 - 调用上下文管理器的
__enter()__方法。 - 如果
with表达式包含as VAR,那么EXPR的返回值被赋值给VAR。 - 执行
BLOCK中的表达式。 - 调用上下文管理器的
__exit()__方法。如果BLOCK的执行过程中发生了一个异常导致程序退出,那么异常的type、value和traceback(即sys.exc_info()的返回值)将作为参数传递给__exit()__方法。否则,将传递三个None
将这个过程用代码表示,是这样的:
mgr = (EXPR) exit = type(mgr).__exit__ # 这里没有执行 value = type(mgr).__enter__(mgr) exc = True try: try: VAR = value # 如果有 as VAR BLOCK except: exc = False if not exit(mgr, *sys.exc_info()): raise finally: if exc: exit(mgr, None, None, None)
- 如果上下文管理器中没有
__enter()__或者__exit()__中的任意一个方法,那么解释器会抛出一个AttributeError。 - 在
BLOCK中发生异常后,如果__exit()__方法返回一个可被看成是True的值,那么这个异常就不会被抛出,后面的代码会继续执行。
千里之行,始于足下
浙公网安备 33010602011771号