原理

  1. 执行 contextor 以获取上下文管理器
  2. 加载上下文管理器的 exit() 方法以备稍后调用
  3. 调用上下文管理器的 enter() 方法
  4. 如果有 as var 从句,则将 enter() 方法的返回值赋给 var
  5. 执行子代码块 with_body
  6. 调用上下文管理器的 exit() 方法,如果 with_body 的退出是由异常引发的,那么该异常的 type、value 和 traceback 会作为参数传给 exit(),否则传三个 None
  7. 如果 with_body 的退出由异常引发,并且 exit() 的返回值等于 False,那么这个异常将被重新引发一次;如果 exit() 的返回值等于 True,那么这个异常就被无视掉,继续执行后面的代码

事务示例

class Resource(object):
    def __enter__(self):
        # 处理一些事务
        print('===connect to resource===')
        # 返回当前对象
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        # 离开是处理一些事务
        print('===close resource connection===')

    # 执行的方法
    def operate(self):
        print('===in operation===')


# 
with Resource() as res:
    res.operate()

数据库示例

上文(__enter__)创建数据库连接
"中文": 数据库操作
下文(__exit__)释放数据库连接
with会自动调用__enter__和__exit__这两个上下文管理器协议

文件示例

上文(__enter__)打开文件
"中文": 操作文件
下文(__exit__)关闭文件
with会自动调用__enter__和__exit__这两个上下文管理器协议

参考