Zac*_*Zac 8 python exception generator coroutine
我在python中有一个协程(增强型生成器),在数据结束后要执行一些代码:
def mycoroutine():
try:
while True:
data = (yield)
print data
finally:
raise ValueError
print "END"
co = mycoroutine()
co.next()
for i in (1,2,3):
co.send(i)
Run Code Online (Sandbox Code Playgroud)
该ValueError异常没有提出,但解释简单地打印:
Exception ValueError: ValueError() in <generator object mycoroutine at 0x2b59dfa23d20> ignored
Run Code Online (Sandbox Code Playgroud)
有没有办法在调用者中捕获异常?
Mar*_*ers 12
唯一的例外是引发.finally当发电机关闭时执行该块.关闭生成器是通过在生成器上下文中引发GeneratorExit异常来完成的.
忽略异常,因为生成器在被删除之前不会被关闭(在这种情况下,当Python退出时自动生成); 生成器__del__处理程序关闭生成器,触发finally:块:
>>> def mycoroutine():
... try:
... while True:
... data = (yield)
... print data
... finally:
... raise ValueError
... print "END"
...
>>> co = mycoroutine()
>>> co.next()
>>> co.close()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in mycoroutine
ValueError
>>> co = mycoroutine()
>>> co.next()
>>> del co
Exception ValueError: ValueError() in <generator object mycoroutine at 0x1046a9fa0> ignored
Run Code Online (Sandbox Code Playgroud)
清理过程中出现的异常总是被忽略; 看object.__del__()文档:
警告:由于
__del__()调用方法的不稳定情况,将忽略执行期间发生的异常,并打印警告sys.stderr.
解决方案是在清理生成器时不会引发异常,或通过显式关闭生成器来捕获异常:
>>> co = mycoroutine()
>>> co.next()
>>> try:
... co.close()
... except ValueError:
... pass
...
>>> del co
>>> # No exception was raised
...
Run Code Online (Sandbox Code Playgroud)
您还可以捕获GeneratorExit异常并在此时执行一些清理:
def mycoroutine():
try:
while True:
data = (yield)
print data
except GeneratorExit:
print "Generator exiting!"
Run Code Online (Sandbox Code Playgroud)
但请注意除了StopIteration或GeneratorExit将要传播的任何例外; 看generator.close()文档:
如果生成器函数然后提升
StopIteration(通过正常退出,或者由于已经关闭)或GeneratorExit(通过不捕获异常),关闭返回其调用者.如果生成器产生一个值,RuntimeError则引发a.如果生成器引发任何其他异常,它将传播给调用者.