Sno*_*all 4 python generator coroutine python-2.7
我正试图捕获生成器调用者抛出的异常:
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
Run Code Online (Sandbox Code Playgroud)
这输出
$ python x.py
0
Traceback (most recent call last):
File "x.py", line 14, in <module>
raise MyException
__main__.MyException
Run Code Online (Sandbox Code Playgroud)
当我打算输出它时
$ python x.py
0
handled exception
1
handled exception
2
handled exception
Run Code Online (Sandbox Code Playgroud)
回想起来,我认为这是因为调用者与生成器的堆栈不同,因此异常不会冒泡到生成器.那是对的吗?是否有其他方法来捕获调用者中引发的异常?
旁白:我可以使用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())
Run Code Online (Sandbox Code Playgroud)
你可能会想到,当执行yield器在生成器中命中时,生成器执行for循环体,有点像Ruby函数yield和块.这不是Python中的工作方式.
当执行命中时yield,生成器的堆栈帧被挂起并从堆栈中移除,并且控制返回到(隐式)调用生成器next方法的代码.然后该代码进入循环体.在引发异常时,生成器的堆栈帧不在堆栈中,并且异常在发生气泡时不会通过生成器.
生成器无法响应此异常.