上下文管理器是实现两个魔术方法__enter__()并且__exit__()(尽管它也可以实现其他方法)的任何对象:
class AContextManager(): def __enter__(self): print("Entered") # 可选地返回一个对象 return "A-instance" def __exit__(self, exc_type, exc_value, traceback): print("Exited" + (" (with an exception)" if exc_type else "")) # 如果要抑制该异常,则返回True
如果上下文退出时的异常,关于异常的信息将被作为三通过exc_type,exc_value,traceback(这是由返回相同的变量函数)。如果上下文正常退出,则所有这三个参数均为。sys.exc_info()None
如果发生异常并将其传递给__exit__方法,则该方法可以返回True以抑制该异常,否则该异常将在__exit__函数末尾重新引发。
with AContextManager() as a: print("a is %r" % a) # 已输入 # 一个是“ A实例” # 已退出 with AContextManager() as a: print("a is %d" % a) # 已输入 # 已退出 (with an exception) # 追溯(最近一次通话): # File "<stdin>", line 2, in <module> # TypeError:%d格式:必须为数字,而不是str
请注意,在第二个示例中,即使在with语句主体的中间发生__exit__异常,在异常传播到外部作用域之前,处理程序仍会执行。
如果只需要一个__exit__方法,则可以返回上下文管理器的实例:
class MyContextManager: def __enter__(self): return self def __exit__(self): print('something')