Why does next raise a #39;StopIteration#39;, but #39;for#39; do a normal return?(为什么 next 会引发“StopIteration,但“for会正常返回?)
问题描述
在这段代码中,为什么使用 for 导致没有 StopIteration还是 for 循环捕获所有异常然后静默退出?在这种情况下,为什么我们会有多余的 return??或者是raise StopIteration 导致:return None?
In this piece of code, why does using for result in no StopIteration
or is the for loop trapping all exceptions and then silently exiting?
In which case, why do we have the extraneous return?? Or is the
raise StopIteration caused by: 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 是什么时候生成的?
Assuming StopIteration is being triggered by: return None.
When is GeneratorExit generated?
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??
在这种情况下,为什么我看不到回溯?
In which case why don't I see a traceback?
推荐答案
for 循环显式监听 StopIteration.
for 语句的目的是循环遍历迭代器提供的序列,异常用于表示迭代器现在完成;for 不会捕获被迭代的对象引发的其他异常,只是那个.
The purpose of the for statement is to loop over the sequence provided by an iterator and the exception is used to signal that the iterator is now done; for doesn't catch other exceptions raised by the object being iterated over, just that one.
这是因为 StopIteration 是正常的、预期的信号,它告诉正在迭代的任何人没有更多的东西要产生.
That's because StopIteration is the normal, expected signal to tell whomever is iterating that there is nothing more to be produced.
生成器函数是一种特殊的迭代器;它确实会在函数完成时引发 StopIteration(即,当它返回时,是的,return None 引发 StopIteration).这是迭代器的要求;他们必须在完成后提出StopIteration;事实上,一旦一个 StopIteration 被引发,试图从他们那里获取另一个元素(通过 next(),或者调用 .next() (py 2) 或 .__next__() (py 3) 迭代器上的方法)必须总是再次引发 StopIteration.
A generator function is a special kind of iterator; it indeed raises StopIteration when the function is done (i.e. when it returns, so yes, return None raises StopIteration). It is a requirement of iterators; they must raise StopIteration when they are done; in fact, once a StopIteration has been raised, attempting to get another element from them (through next(), or calling the .next() (py 2) or .__next__() (py 3) method on the iterator) must always raise StopIteration again.
GeneratorExit 是向other 方向通信的异常.您正在显式关闭一个带有 yield 表达式的生成器,Python 将该关闭传递给生成器的方式是在该函数内部引发 GeneratorExit.您在 countdown 中显式捕获该异常,其目的是让生成器在关闭时根据需要清理资源.
GeneratorExit is an exception to communicate in the other direction. You are explicitly closing a generator with a yield expression, and the way Python communicates that closure to the generator is by raising GeneratorExit inside of that function. You explicitly catch that exception inside of countdown, its purpose is to let a generator clean up resources as needed when closing.
GeneratorExit 不会传播给调用者;请参阅 generator.close() 文档一个>.
A GeneratorExit is not propagated to the caller; see the generator.close() documentation.
这篇关于为什么 next 会引发“StopIteration",但“for"会正常返回?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么 next 会引发“StopIteration",但“for&qu
基础教程推荐
- 在Python中从Azure BLOB存储中读取文件 2022-01-01
- 包装空间模型 2022-01-01
- 在同一图形上绘制Bokeh的烛台和音量条 2022-01-01
- 使用大型矩阵时禁止 Pycharm 输出中的自动换行符 2022-01-01
- Plotly:如何设置绘图图形的样式,使其不显示缺失日期的间隙? 2022-01-01
- PANDA VALUE_COUNTS包含GROUP BY之前的所有值 2022-01-01
- 修改列表中的数据帧不起作用 2022-01-01
- 求两个直方图的卷积 2022-01-01
- PermissionError: pip 从 8.1.1 升级到 8.1.2 2022-01-01
- 无法导入 Pytorch [WinError 126] 找不到指定的模块 2022-01-01
