Python PEP479 更改生成器内部的 StopIteration 处理 [英] Python PEP479 Change StopIteration handling inside generators
问题描述
有人能帮我理解 PEP479 是关于什么的吗?我正在阅读文档并且无法理解它.
摘要说:
<块引用>此 PEP 提议对生成器进行更改:当在生成器内部引发 StopIteration 时,将其替换为 RuntimeError.(更准确地说,这发生在异常即将从生成器的堆栈帧中冒出时.)
例如,像这样的循环是否仍然有效?
it = iter([1,2,3])尝试:我 = 下一个(它)为真:我 = 下一个(它)除了停止迭代:经过
或者这是否意味着如果我有这样的生成器定义:
def gen():从范围(5)的产量引发停止迭代
StopIteration
将被替换为 RuntimeError
?
如果有人能对此有所了解,我将不胜感激.
你的第一个循环应该仍然有效——StopIteration
在生成器耗尽时仍然会被引发.
不同之处在于,在生成器中引发 StopIteration
时, 会产生歧义.它被引发(隐式)是因为生成器用完了要让出的东西 - 还是因为委托生成器用完要让出的东西(可能是由于 next
调用)和异常没有正确处理?PEP-0479 试图解决这种歧义.现在,如果您获得 StopIteration
,则意味着您正在使用的生成器耗尽了要生成的项目.换句话说,这意味着委托生成器没有在项目用完时处理不当.
为了支持这个改变,你的生成器应该return
而不是显式提高StopIteration
.
def gen():从范围(5)的产量返回
<小时>
如果你在启用 StopIteration
和 generator_stop
的情况下尝试它会发生什么(当 python3.7 出现时这将成为默认值):
Could someone help me understand what PEP479 is about? I was reading the doc and couldn't get my head around it.
The abstract says:
This PEP proposes a change to generators: when StopIteration is raised inside a generator, it is replaced it with RuntimeError. (More precisely, this happens when the exception is about to bubble out of the generator's stack frame.)
So for example, does a loop like so still work?
it = iter([1,2,3])
try:
i = next(it)
while True:
i = next(it)
except StopIteration:
pass
Or does it mean that if I have a generator definition like so:
def gen():
yield from range(5)
raise StopIteration
the StopIteration
is going to be replaced with RuntimeError
?
I would really appreciate if someone could shed some light on this.
Your first loop should still work -- StopIteration
will still be raised when a generator is exhausted.
The difference is that there was ambiguity when a StopIteration
was raised in a generator. Did it get raised (implicitly) because the generator ran out of things to yield -- Or did it get raised because a delegate generator ran out of things to yield (maybe due to a next
call) and the exception wasn't handled properly? PEP-0479 tries to address that ambiguity. Now if you get a StopIteration
, it means that the generator you are working with ran out items to yield. Said another way, it means that a delegate generator didn't get mis-handled when running out of items.
To support this change, your generator should return
instead of raising StopIteration
explicitly.
def gen():
yield from range(5)
return
Here's what happens if you try it with the StopIteration
and generator_stop
enabled (which will become the default when python3.7 comes around):
>>> from __future__ import generator_stop
>>> def gen():
... yield from range(5)
... raise StopIteration
...
>>> list(gen())
Traceback (most recent call last):
File "<stdin>", line 3, in gen
StopIteration
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: generator raised StopIteration
这篇关于Python PEP479 更改生成器内部的 StopIteration 处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!