在线文档教程

Types: 11. Context Manager Types

11. Context Manager Types

2.5版本中的新功能。

Python的with语句支持由上下文管理器定义的运行时上下文的概念。这是通过使用两个独立的方法实现的,它们允许用户定义的类定义在执行语句正文前输入的运行时上下文,并在语句结束时退出。

上下文管理协议由一对需要被提供用于上下文管理器对象来定义一个运行时环境的方法:

contextmanager.__enter__()

输入运行时上下文并返回此对象或与运行时上下文相关的另一个对象。此方法返回的值绑定到使用此上下文管理器aswith语句子句中的标识符。

一个返回自身的上下文管理器的例子是一个文件对象。文件对象从__enter __()返回,以允许open()with语句中用作上下文表达式。

返回相关对象的上下文管理器的示例是返回的对象decimal.localcontext()。这些管理器将激活的小数上下文设置为原始小数上下文的副本,然后返回副本。这允许对with语句正文中的当前小数上下文进行更改,而不影响with语句外的代码。

contextmanager.__exit__(exc_type, exc_val, exc_tb)

退出运行时环境并返回一个布尔标志,指示是否应该抑制发生的任何异常。如果执行with语句正文时发生异常,则参数将包含异常类型,值和追溯信息。否则,所有三个参数都是None

从此方法返回一个真值将导致with语句禁止该异常,并继续执行语句之后的with语句。否则在该方法执行完成后异常继续传播。在执行此方法期间发生的异常将替换发生在with语句正文中的任何异常。

传入的异常不应该显式重新显示 - 相反,此方法应该返回一个false值,以指示该方法已成功完成,并且不希望抑制引发的异常。这允许上下文管理代码(例如contextlib.nested)容易地检测__exit__()方法是否实际上已经失败。

Python定义了几个上下文管理器来支持简单的线程同步,及时关闭文件或其他对象,并简化对活动的十进制算术上下文的操作。特定的类型没有特别对待它们的上下文管理协议的实现。有关contextlib示例,请参阅模块。

Python的生成器和contextlib.contextmanager 装饰器提供了实现这些协议的便捷方式。如果一个生成器函数用contextlib.contextmanager装饰器修饰,它将返回一个实现必要__enter__()__exit__()方法的上下文管理器,而不是由未修饰的生成器函数生成的迭代器。

请注意,Python / C API中的Python对象的类型结构中没有任何这些方法的特定插槽。想要定义这些方法的扩展类型必须提供它们作为普通的Python可访问方法。与设置运行时环境的开销相比,单个类字典查找的开销可以忽略不计。