捕获Python中生成器调用程序中引发的异常 [英] Catch exception thrown in generator caller in Python

查看:139
本文介绍了捕获Python中生成器调用程序中引发的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试捕获生成器调用者中引发的异常:

I'm trying to catch an exception thrown in the caller of a generator:

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

调用方的堆栈与生成器的堆栈不同,因此不会将异常冒泡到生成器。 对吗?还有其他方法可以捕获调用方引发的异常吗?

In retrospect, I think this is because the caller has a different stack from the generator, so the exception isn't bubbled up to the generator. Is that correct? Is there some other way to catch exceptions raised in the caller?

在旁边:我可以使其正常工作使用 generator.throw(),但这需要修改调用者:

Aside: I can make it work using generator.throw(), but that requires modifying the caller:

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())


推荐答案

您可能会认为,当执行达到收益在生成器中,生成器执行 for 循环的主体,有点像具有 yield 的Ruby函数。和一个街区。

You may be thinking that when execution hits yield in the generator, the generator executes the body of the for loop, sort of like a Ruby function with yield and a block. That's not how things work in Python.

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

When execution hits yield, the generator's stack frame is suspended and removed from the stack, and control returns to the code that (implicitly) called the generator's next method. That code then enters the loop body. At the time the exception is raised, the generator's stack frame is not on the stack, and the exception does not go through the generator as it bubbles up.

生成器具有无法应对这种异常。

The generator has no way to respond to this exception.

这篇关于捕获Python中生成器调用程序中引发的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆