python contextmanager 如何将异常重新引发回装饰生成器?

问题描述

这是一个关于 contextmanager 如何做它所做的事情的问题。

contextmanger 是一个装饰器,它调用被装饰的函数(一个生成器)两次,以构建 __enter____exit__ 函数,由 with条款,到目前为止一切顺利。我不明白的是——当在 with 块内引发异常时,生成器内的 except 怎么能捕获它吗?

@contextmanager
def f():
    try:
        yield 'foo'
    except Exception as e:
        print('How can I ever reach here??')
        print(e)
    finally:
        print('finally')

with f() as p:
    print(p)
    raise Exception('bar')

输出是

foo
How can I ever reach here??
bar
finally

我认为魔法发生在 @contextmanager 中,因为如果我移除装饰器,并且只在 try 块内执行“yield”,则生成器内部不会捕获生成器外部的异常:

def f():
    try:
        yield 'foo'
    except Exception as e:
        print('How can I ever reach here??')
        print(e)
    finally:
        print('finally')

g = f()
print(next(g))
raise Exception('bar')

输出是

foo
Traceback (most recent call last):
...
Exception: bar

我查看了 contextlib.contextmanager 代码,但仍然无法弄清楚使用纯 python 代码如何做到这一点。关于我在这里错过的语言的一些基本知识?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)