[英]Avoid “exception ignored” in python enhanced generator
I have a coroutine (Enhanced generators) in python with some code to be executed after the end of data: 我在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)
The ValueError
exception is not raised but the interpreter simply prints: 不会引发
ValueError
异常,但解释器只会打印:
Exception ValueError: ValueError() in <generator object mycoroutine at 0x2b59dfa23d20> ignored
Is there a way to catch the exception in the caller? 有没有办法在调用者中捕获异常?
The exception is raised. 该异常 。 The
finally
block is executed when the generator is closed. 当发电机关闭时执行
finally
块。 Closing a generator is done by raising a GeneratorExit
exception in the generator context. 关闭生成器是通过在生成器上下文中引发
GeneratorExit
异常来完成的。
The exception in ignored because the generator isn't closed until it is being deleted (automatically in this case, when Python exits); 忽略异常,因为生成器在被删除之前不会被关闭(在这种情况下,当Python退出时自动生成); the generator
__del__
handler closes the generator, which triggers the finally:
block: 生成器
__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
Exceptions raised during cleanup are always ignored; 清理过程中出现的异常总是被忽略; see the
object.__del__()
documentation : 看到
object.__del__()
文档 :
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.警告 :由于调用
__del__()
方法的不稳定情况,将忽略执行期间发生的异常,并向sys.stderr
警告。
The solution is to not have exceptions being raised when a generator is cleaned up, or catch the exception by closing the generator explicitly: 解决方案是在清理生成器时不会引发异常,或通过显式关闭生成器来捕获异常:
>>> co = mycoroutine()
>>> co.next()
>>> try:
... co.close()
... except ValueError:
... pass
...
>>> del co
>>> # No exception was raised
...
You could also catch the GeneratorExit
exception and perform some cleanup at that point: 您还可以捕获
GeneratorExit
异常并在此时执行一些清理:
def mycoroutine():
try:
while True:
data = (yield)
print data
except GeneratorExit:
print "Generator exiting!"
but note that any exception other than StopIteration
or GeneratorExit
will always be propagated; 但请注意,除了
StopIteration
或GeneratorExit
之外的任何异常都将被传播; see the generator.close()
documentation : 请参阅
generator.close()
文档 :
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.如果生成器函数然后引发
StopIteration
(通过正常退出,或者由于已经关闭)或GeneratorExit
(通过不捕获异常),则关闭返回其调用者。 If the generator yields a value, aRuntimeError
is raised.如果生成器产生一个值,则引发
RuntimeError
。 If the generator raises any other exception, it is propagated to the caller.如果生成器引发任何其他异常,它将传播给调用者。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.