Python编写自己的上下文管理器

示例

上下文管理器是实现两个魔术方法__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')