避免“忽略异常”在python增强发电机 [英] Avoid "exception ignored" in python enhanced generator
问题描述
我在python中有一个协同程序(增强型生成器),一些代码在数据结束后执行:
I have a coroutine (Enhanced generators) in python with some code to be executed after the end of data:
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
异常不是但是解释器只是打印出来:
The ValueError
exception is not raised but the interpreter simply prints:
Exception ValueError: ValueError() in <generator object mycoroutine at 0x2b59dfa23d20> ignored
有没有办法捕获调用者中的异常?
Is there a way to catch the exception in the caller?
推荐答案
引发异常 。当发电机关闭时,执行 finally
块。关闭生成器是通过提高 GeneratorExit
exception 在生成器上下文中。
The exception is raised. The finally
block is executed when the generator is closed. Closing a generator is done by raising a GeneratorExit
exception in the generator context.
异常被忽略,因为生成器在被删除之前没有被关闭当Python退出时);生成器 __ del __
处理程序关闭生成器,最终触发块:
块:
The exception in ignored because the generator isn't closed until it is being deleted (automatically in this case, when Python exits); the generator __del__
handler closes the generator, which triggers the 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
清理期间引发的异常总是被忽略;请参阅 对象.__ del __()
文档:
Exceptions raised during cleanup are always ignored; see the object.__del__()
documentation:
警告:由于
__ 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
...
你也可以抓住 GeneratorExit
异常,然后执行一些清理:
You could also catch the GeneratorExit
exception and perform some cleanup at that point:
def mycoroutine():
try:
while True:
data = (yield)
print data
except GeneratorExit:
print "Generator exiting!"
但请注意除 StopIteration
之外的任何异常或 GeneratorExit
将始终传播;请参阅 generator.close()
文档:
but note that any exception other than StopIteration
or GeneratorExit
will always be propagated; see the generator.close()
documentation:
如果生成器函数然后引发
StopIteration
(通常退出或由于已经关闭)或GeneratorExit
(通过不捕获异常),close返回给它的调用者。如果生成器产生一个值,则会引发RuntimeError
。如果生成器引发任何其他异常,它将传播给调用者。
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增强发电机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!