我正在 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/