Python生成器,'coroutine'中出现非滚动异常

2024-05-19 12:24:39 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

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

其输出:

^{pr2}$

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

有人能解释一下为什么这个功能能正常工作,以及为什么生成器中的except没有吞下异常?在

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


Tags: inselffordefexceptionclassraiseprint
2条回答

你的代码并不像你想的那样。不能在这样的协同进程中引发异常。而是捕捉^{}异常。查看使用不同的异常时会发生什么:

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

由于这仍然会获得赞成票,下面是在生成器中引发异常的方法:

^{pr2}$

有关^{},请参阅文档。在

编辑:THC4k说了什么。在

如果确实要在生成器内部引发任意异常,请使用throw方法:

>>> def Gen():
...     try:
...             yield 1
...     except Exception:
...             print "Excepted."
...
>>> foo = Gen()
>>> next(foo)
1
>>> foo.throw(Exception())
Excepted.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

您会注意到您在顶层得到了一个StopIteration。它们是由元素用完的生成器引发的;它们通常被for循环吞并,但在本例中,我们让生成器引发异常,因此循环不会注意到它们。在

相关问题 更多 >