我最近在 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/