捕获Python中生成器调用程序中引发的异常 [英] Catch exception thrown in generator caller in 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屋!