9.22 定义上下文管理器的简单方法

    实现一个新的上下文管理器的最简单的方法就是使用 模块中的 装饰器。下面是一个实现了代码块计时功能的上下文管理器例子:

    在函数 timethis() 中,yield 之前的代码会在上下文管理器中作为 方法执行,所有在 yield 之后的代码会作为 exit() 方法执行。如果出现了异常,异常会在yield语句那里抛出。

    下面是一个更加高级一点的上下文管理器,实现了列表对象上的某种事务:

    这段代码的作用是任何对列表的修改只有当所有代码运行完成并且不出现异常的情况下才会生效。下面我们来演示一下:

    通常情况下,如果要写一个上下文管理器,你需要定义一个类,里面包含一个 enter() 和一个 方法,如下所示:

    @contextmanager 应该仅仅用来写自包含的上下文管理函数。如果你有一些对象(比如一个文件、网络连接或锁),需要支持 with 语句,那么你就需要单独实现 方法和 exit() 方法。

    原文: