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

上下文管理器:异常路径也要释放资源

把清理动作写在函数末尾,无法覆盖中途抛异常的情况。with 语句把资源作用域放到语法结构里,退出时调用清理协议。

▶ 本文含视频讲解
▶ 教学视频手动播放 · 英语讲解

Learn Python — Full Course for Beginners

Python 入门课程作为语法与编程背景复习;本文使用的较新标准库特性不保证在该课程中逐项覆盖。此为外部原版课程,多篇笔记可能共用;未剪辑为本文专属视频。

播放器需要能访问 YouTube 的网络;若这里无法加载,可打开原视频。本文与本地图解仍可独立阅读。

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

问题从哪里出现

把清理动作写在函数末尾,无法覆盖中途抛异常的情况。with 语句把资源作用域放到语法结构里,退出时调用清理协议。

理解核心机制

contextmanager 装饰器可以把获取、yield 和释放组合起来。释放部分通常放进 finally,这样正常返回和异常退出都会执行。不要无意吞掉主体异常。

动手做一个小实验

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

Python17 行 · 可横向滚动
from contextlib import contextmanager
events = []
@contextmanager
def resource():
    events.append("open")
    try:
        yield "handle"
    finally:
        events.append("close")

try:
    with resource() as handle:
        raise ValueError(handle)
except ValueError:
    pass
assert events == ["open", "close"]
print(events)

适用边界与常见误区

清理函数自身也可能失败,甚至遮蔽原始错误。数据库提交与关闭是不同操作,不能用资源释放代替事务设计。

继续练习

让主体分别正常结束、提前返回和抛出异常,记录清理次数,确保每条路径恰好执行一次。

参考资料

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

← 返回文章归档