避免“忽略异常”在python增强发电机 [英] Avoid "exception ignored" in python enhanced generator

查看:208
本文介绍了避免“忽略异常”在python增强发电机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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) or GeneratorExit (by not catching the exception), close returns to its caller. If the generator yields a value, a RuntimeError is raised. If the generator raises any other exception, it is propagated to the caller.

这篇关于避免“忽略异常”在python增强发电机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆