python - 在 Python 中捕获生成器调用者抛出的异常

标签 python python-2.7 generator coroutine

我正在 try catch 生成器调用者抛出的异常:

class MyException(Exception):
    pass

def gen():
    for i in range(3):
        try:
            yield i
        except MyException:
            print 'handled exception'

for i in gen():
    print i
    raise MyException

这输出

$ python x.py
0
Traceback (most recent call last):
  File "x.py", line 14, in <module>
    raise MyException
__main__.MyException

当我打算让它输出的时候

$ python x.py
0
handled exception
1
handled exception
2
handled exception

回想起来,我认为这是因为调用者与生成器有不同的堆栈,所以异常没有冒泡到生成器。 这是正确的吗?有没有其他方法可以捕获调用方引发的异常?

旁白:我可以使用 generator.throw() 让它工作,但这需要修改调用者:

def gen():
    for i in range(3):
        try:
            yield i
        except MyException:
            print 'handled exception'
            yield

import sys
g = gen()
for i in g:
    try:
        print i
        raise MyException
    except:
        g.throw(*sys.exc_info())

最佳答案

您可能会想,当执行命中生成器中的 yield 时,生成器会执行 for 循环的主体,有点像带有 的 Ruby 函数yield 和一个 block 。这不是 Python 中的工作方式。

当执行到 yield 时,生成器的栈帧被挂起并从堆栈中移除,控制权返回到(隐式)调用生成器的 next 方法的代码。然后该代码进入循环体。在引发异常时,生成器的堆栈帧不在堆栈上,并且异常在冒泡时不会通过生成器。

生成器无法响应此异常。

关于python - 在 Python 中捕获生成器调用者抛出的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44598548/

相关文章:

Python:检查命名元组列表是否包含特定属性值

python - 如何制作一个函数,一次返回一个列表中的项目?

python - 迭代字符串追加的时间复杂度实际上是 O(n^2) 还是 O(n)?

python - 所有中心都在 K-Means 聚类上重合

python - Scipy:距离相关性高于1

python - 如何获取元素在列表中出现的次数 Python

python,dijkstra的最短路径,类型错误 - 生成器不支持项目分配

javascript - 将 ES6 生成器与 XMLHttpRequest 结合使用

python - 带有不在模型中的额外字段的 Django ModelForm

python - 使用 Python 脚本将长视频切成 FFMPEG 中的 block