WMX · 随记
·Python· 3 分钟阅读

ExitStack:运行时才知道数量的资源怎么清理

同时打开几份文件时可以嵌套 with,但数量由输入决定时,固定语法层级就不方便。资源获取到一半失败,也需要释放前面已经取得的资源。

Python 系列概览:输入校验、数据处理与行为验证
Python 系列概览:输入校验、数据处理与行为验证 点击图片查看大图 ↗

问题从哪里出现

同时打开几份文件时可以嵌套 with,但数量由输入决定时,固定语法层级就不方便。资源获取到一半失败,也需要释放前面已经取得的资源。

理解核心机制

ExitStack 动态登记上下文或清理回调,并按逆序退出。每次成功获取后立即登记释放,能让部分初始化失败得到正确处理。

动手做一个小实验

Python 3.11 或更新版本,仅使用标准库;将示例保存为 demo.py 后执行 python3 demo.py。

Python8 行 · 可横向滚动
from contextlib import ExitStack
from io import StringIO
handles = []
with ExitStack() as stack:
    for text in ("alpha", "beta", "gamma"):
        handles.append(stack.enter_context(StringIO(text)))
    print([handle.read() for handle in handles])
assert all(handle.closed for handle in handles)

适用边界与常见误区

回调顺序与上下文异常传播有关,不能随意把存在依赖的资源交换顺序。异步资源应考虑 AsyncExitStack,避免混用同步关闭协议。

继续练习

在获取第二个资源后抛异常,记录清理顺序;再用 callback 登记一个普通清理函数,比较两种登记方式。

参考资料

阅读相关官方文档或原始资料 ↗

← 返回文章归档