我在 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)
未引发 ValueError
异常,但解释器只是打印:
Exception ValueError: ValueError() in <generator object mycoroutine at 0x2b59dfa23d20> ignored
有没有办法在调用者中捕获异常?
最佳答案
引发了异常。 finally
block 在生成器关闭时执行。关闭生成器是通过调用 GeneratorExit
exception 来完成的。在生成器上下文中。
异常被忽略,因为生成器在被删除之前不会关闭(在这种情况下,当 Python 退出时自动关闭);生成器 __del__
处理程序关闭生成器,这会触发 finally:
block :
>>> 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
清理期间引发的异常总是被忽略;查看object.__del__()
documentation :
Warning: Due to the precarious circumstances under which
__del__()
methods are invoked, exceptions that occur during their execution are ignored, and a warning is printed tosys.stderr
instead.
解决方案是在清理生成器时不引发异常,或者通过显式关闭生成器来捕获异常:
>>> co = mycoroutine()
>>> co.next()
>>> try:
... co.close()
... except ValueError:
... pass
...
>>> del co
>>> # No exception was raised
...
您还可以捕获 GeneratorExit
异常并在此时执行一些清理:
def mycoroutine():
try:
while True:
data = (yield)
print data
except GeneratorExit:
print "Generator exiting!"
但请注意,除了 StopIteration
或 GeneratorExit
之外的任何异常都将始终被传播;查看generator.close()
documentation :
If the generator function then raises
StopIteration
(by exiting normally, or due to already being closed) orGeneratorExit
(by not catching the exception), close returns to its caller. If the generator yields a value, aRuntimeError
is raised. If the generator raises any other exception, it is propagated to the caller.
关于python - 在 python 增强生成器中避免 "exception ignored",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18637048/