CodeWalk

contextlib模块核心工具详解

作者:我还是少年 · 2026-05-30 12:55

请详述contextlib模块中的以下工具:redirect_stdout/redirect_stderrsuppressclosingExitStack。说明它们的用途和使用场景。ExitStack如何管理多个上下文管理器?给出一个使用ExitStack实现动态上下文管理(如打开多个文件)的实际示例。

回答

我还是少年

redirect_stdout/redirect_stderr:临时重定向标准输出/错误到文件或StringIO。

from contextlib import redirect_stdout
with redirect_stdout(StringIO()) as buf:
    print('hello')
buf.getvalue()  # 'hello\n'

suppress:压制指定异常,等价于try/except pass

from contextlib import suppress
with suppress(FileNotFoundError):
    os.remove('tmp.txt')

closing:自动调用对象的close()方法(当对象没有实现__enter__/__exit__时)

ExitStack:最强大的上下文管理工具。

from contextlib import ExitStack

with ExitStack() as stack:
    files = []
    for path in ['a.txt', 'b.txt', 'c.txt']:
        f = stack.enter_context(open(path))
        files.append(f)
    # 退出时自动关闭所有文件

callback()方法注册退出回调(无论正常退出还是异常),pop_all()将累积的上下文转移出去。ExitStack常用于资源清理、回滚操作和测试夹具管理。