一些常用的上下文管理库

closing

如果对象提供了 close() 方法,但没有实现 enter/exit 协议,那么可以使用这个函数构建上下文管理器。

suppress

“构建临时忽略指定异常的上下文管理器。

@contextmanager

  这个装饰器把简单的生成器函数变成上下文管理器,这样就不用创建类去实现管理器协议了。

能减少创建上下文管理器的样板代码量,因为不用编写一个完整的类,定义 enterexit 方法,而只需实现有一个 yield 语句的生成器,生成想让 enter 方法返回的值。

在使用 @contextmanager 装饰的生成器中,yield 语句的作用是把函数的定义体分成两部分:yield 语句前面的所有代码在 with 块开始时(即解释器调用 enter 方法时)执行, yield 语句后面的代码在 with 块结束时(即调用 exit 方法时)执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import contextlib


@contextlib.contextmanager
def t():
print('begin')
try:
yield 'ttt'
except Exception as e:
print(e)
print('after')
return True


with t() as tt:
print('withing',tt)
###
begin
withing ttt
after

需要显式处理异常

ContextDecorator

  这是个基类,用于定义基于类的上下文管理器。这种上下文管理器也能用于装饰函数,在受管理的上下文中运行整个函数。

ExitStack

  这个上下文管理器能进入多个上下文管理器。with 块结束时,ExitStack 按照后进先出的顺序调用栈中各个上下文管理器的 exit 方法。如果事先不知道 with 块要进入多少个上下文管理器,可以使用这个类。例如,同时打开任意一个文件列表中的所有文件