11

有人可以帮我理解 PEP479 是关于什么的吗?我正在阅读文档,无法理解它。

摘要说:

这个 PEP 建议对生成器进行更改:当在生成器中引发 StopIteration 时,它会被 RuntimeError 替换。(更准确地说,当异常即将从生成器的堆栈帧中冒出时,就会发生这种情况。)

例如,这样的循环是否仍然有效?

it = iter([1,2,3])
try:
    i = next(it)
    while True:
        i = next(it)
except StopIteration:
    pass

或者这是否意味着如果我有这样的生成器定义:

def gen():
    yield from range(5)
    raise StopIteration

StopIteration被替换为RuntimeError?

如果有人能对此有所了解,我将不胜感激。

4

1 回答 1

15

你的第一个循环应该仍然可以工作——StopIteration当发电机耗尽时仍然会被提升。

不同之处在于,生成器中提出 a时存在歧义StopIteration。它是因为生成器没有东西可以产生而被引发(隐式) - 还是因为委托生成器没有东西可以产生(可能是由于next调用)并且异常没有被正确处理而被引发?PEP-0479 试图解决这种歧义。现在如果你得到一个StopIteration,这意味着你正在使用的生成器用完了项目来生产。换句话说,这意味着委托生成器在项目用完时不会被错误处理。

为了支持这种变化,你的生成器应该return而不是显式地提升StopIteration

def gen():
    yield from range(5)
    return

如果您尝试启用StopIterationand会发生以下generator_stop情况(当 python3.7 出现时,这将成为默认设置):

>>> 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
于 2016-06-08T15:56:20.490 回答