You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python装饰器无法捕获被装饰生成器函数内部异常问题咨询

结论

你的理解完全正确,当前异常未被捕获就是生成器函数的执行特性导致的。

核心原理说明

只要函数体内包含yield关键字,Python就会将其标记为生成器函数,调用生成器函数时会直接返回生成器迭代器对象,不会执行函数体内的任何代码,你代码里的check(number)逻辑要等到第一次对返回的生成器执行迭代操作时才会运行:

  • 你直接调用dec_mthd_b(1)时,装饰器内的try块仅执行了「创建生成器对象」的逻辑,没有运行check方法,自然不会触发异常,所以不会进入except捕获分支
  • 你可以手动验证该逻辑:先执行gen = dec_mthd_b(1)拿到生成器对象,再执行next(gen)触发迭代,这时候check方法就会运行,异常也会被抛出

你提到的文档中「挂起保留所有异常处理状态」的描述,是指生成器运行到yield暂停时,当前所有的上下文(包括异常处理的作用域、本地变量、执行指针等)都会被保存,下次恢复执行时上下文不会丢失,和你当前遇到的问题逻辑并不冲突。

适配生成器的装饰器修改方案

你当前的装饰器仅包裹了「生成器创建」的流程,要捕获生成器迭代运行时的异常,需要修改装饰器逻辑,将异常捕获包裹在迭代流程中,参考实现如下:

def remediation_decorator(dec_mthd):
    def new_func(*args, **kwargs):
        # 先获取原生成器对象
        origin_gen = dec_mthd(*args, **kwargs)
        try:
            # 驱动原生成器运行,捕获执行过程中抛出的异常
            yield from origin_gen
        except (KeyError, HTTPError) as err:
            print(f'error = {err}... call the remediation function')
    return new_func

修改后你可以通过list(dec_mthd_b(1))触发迭代,即可看到异常被成功捕获的输出。

内容的提问来源于stack exchange,提问作者hitzoglin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 09:24:03