如何通过contextlib.contextmanager在Python中实现自定义上下文管理器?

2026-05-07 11:350阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1113个文字,预计阅读时间需要5分钟。

如何通过contextlib.contextmanager在Python中实现自定义上下文管理器?

它不是装饰任意函数都能上下文管理器的工具——contextlib.contextmanager。本质是把一个生成器函数包装成__enter__和__exit__的实现。关键约束是:

常见错误是写成普通函数、或 yield 多次、或 yield 在 if/else 分支里,这时会报 RuntimeError: generator didn't yield 或更隐蔽的 StopIteration

  • yield 必须存在,且不能被条件语句包裹(比如不能写 if flag: yield
  • yield 后面可以跟一个值,它将成为 with 语句中 as 绑定的对象
  • yield 之后的代码只在退出时执行,无论是否发生异常;若需区分正常退出与异常退出,要手动检查 sys.exc_info()

如何在 yield 后捕获并处理异常

默认情况下,contextlib.contextmanager 把异常原样抛出。如果你需要拦截、记录或压制异常(比如文件关闭失败不中断主流程),就得在 yield 后显式处理 sys.exc_info()

注意:yield 本身不接收参数,但 __exit__ 阶段能拿到三元组 (exc_type, exc_value, traceback),所以得靠 sys.exc_info() 拿到当前异常上下文。

阅读全文
标签:Python

本文共计1113个文字,预计阅读时间需要5分钟。

如何通过contextlib.contextmanager在Python中实现自定义上下文管理器?

它不是装饰任意函数都能上下文管理器的工具——contextlib.contextmanager。本质是把一个生成器函数包装成__enter__和__exit__的实现。关键约束是:

常见错误是写成普通函数、或 yield 多次、或 yield 在 if/else 分支里,这时会报 RuntimeError: generator didn't yield 或更隐蔽的 StopIteration

  • yield 必须存在,且不能被条件语句包裹(比如不能写 if flag: yield
  • yield 后面可以跟一个值,它将成为 with 语句中 as 绑定的对象
  • yield 之后的代码只在退出时执行,无论是否发生异常;若需区分正常退出与异常退出,要手动检查 sys.exc_info()

如何在 yield 后捕获并处理异常

默认情况下,contextlib.contextmanager 把异常原样抛出。如果你需要拦截、记录或压制异常(比如文件关闭失败不中断主流程),就得在 yield 后显式处理 sys.exc_info()

注意:yield 本身不接收参数,但 __exit__ 阶段能拿到三元组 (exc_type, exc_value, traceback),所以得靠 sys.exc_info() 拿到当前异常上下文。

阅读全文
标签:Python