Python生成器, 'coroutine'中的非吞咽异常

标签 python exception generator

我最近在 Python 生成器中发现了一些令人惊讶的行为:

class YieldOne:
  def __iter__(self):
    try:
      yield 1
    except:
      print '*Excepted Successfully*'
      # raise

for i in YieldOne():
  raise Exception('test exception')

给出输出:

*Excepted Successfully*
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
Exception: test exception

*Excepted Successfully* 被打印出来让我(高兴地)感到惊讶,因为这正是我想要的,但也令我惊讶的是异常仍然传播到了顶层。我期望必须使用(在本例中注释)raise 关键字来获得观察到的行为。

谁能解释为什么这个功能会像现在这样工作,以及为什么生成器中的 except 没有吞下异常?

这是 Python 中唯一一个 except 不包含异常的实例吗?

最佳答案

您的代码并没有按照您的想法行事。您不能在这样的协程中引发异常。你要做的是捕捉 GeneratorExit异常(exception)。看看当你使用不同的异常时会发生什么:

class YieldOne:
  def __iter__(self):
    try:
      yield 1
    except RuntimeError:
        print "you won't see this"
    except GeneratorExit:
      print 'this is what you saw before'
      # raise

for i in YieldOne():
  raise RuntimeError

因为这仍然得到赞成票,下面是如何在生成器中引发异常:

class YieldOne:
  def __iter__(self):
    try:
      yield 1
    except Exception as e:
      print "Got a", repr(e)
      yield 2
      # raise

gen = iter(YieldOne())

for row in gen:
    print row # we are at `yield 1`
    print gen.throw(Exception) # throw there and go to `yield 2` 

请参阅 generator.throw 的文档.

关于Python生成器, 'coroutine'中的非吞咽异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3997496/

相关文章:

python - 为什么 python 生成器框架的 (gi_frame) f_back 属性总是没有?

python - 使用 OpenCV python 绑定(bind)索引 channel 数据(numpy 数组)

python - 当if语句至少满足一次时,如何不执行for循环的else语句?

python - 映射后的数字格式?

c# - Sprite 批处理: "Begin cannot be called again until End has been successfully called."

python - 类内的 Nose 测试生成器

关于 Selenium-Element 的 Python 3.7 帮助无法滚动到 View 中

php - 从异常处理程序中触发错误

java - 返回响应实体中断流程

python 生成器到 pandas 数据框