在这段代码中,为什么使用 for
导致没有 StopIteration
还是 for
循环捕获所有异常然后静默退出?
在这种情况下,为什么我们有多余的 return
?或者是raise StopIteration
由:return None
引起?
#!/usr/bin/python3.1
def countdown(n):
print("counting down")
while n >= 9:
yield n
n -= 1
return
for x in countdown(10):
print(x)
c = countdown(10)
next(c)
next(c)
next(c)
假设
StopIteration
被触发: return None
。GeneratorExit
什么时候生成?def countdown(n):
print("Counting down from %d" % n)
try:
while n > 0:
yield n
n = n - 1
except GeneratorExit:
print("Only made it to %d" % n)
如果我手动执行:
c = countdown(10)
c.close() #generates GeneratorExit??
在这种情况下,为什么我看不到回溯?
最佳答案
for
循环显式监听 StopIteration
。for
语句的目的是循环遍历迭代器提供的序列,异常用于表示迭代器现在已完成; for
不会捕获被迭代对象引发的其他异常,只是那个。
那是因为 StopIteration
是正常的、预期的信号,它告诉正在迭代的人没有什么可产生的了。
生成器函数是一种特殊的迭代器;它确实在函数完成时引发 StopIteration
(即当它返回时,是的, return None
引发 StopIteration
)。这是迭代器的要求;完成后,他们必须提高 StopIteration
;事实上,一旦StopIteration
已经提出,试图从他们那里得到另一个元素(通过next()
,或呼吁迭代器.next()
(PY 2)或.__next__()
(PY 3)方法)必须始终再次提高StopIteration
。GeneratorExit
是在另一个方向上通信的异常(exception)。您正在使用 yield
表达式显式关闭生成器,Python 将该关闭传递给生成器的方式是通过在该函数内部引发 GeneratorExit
。您在 countdown
中明确捕获该异常,其目的是让生成器在关闭时根据需要清理资源。GeneratorExit
不会传播给调用者;见 generator.close()
documentation 。
关于python - 为什么接下来会引发 'StopIteration' ,但 'for' 会正常返回?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14413969/