自定义 python 生成器中的返回和停止迭代

Sla*_*off 1 python exception generator python-3.x

阅读 Python 中的一些新风格观点,并开始从生成器StopIterationreturn生成器的转变。我的主要问题是这在自定义生成器中应该如何工作。我有一个类,我__next__直接覆盖了方法,因为我必须添加一些逻辑来跟踪生成。

下面非常接近我正在做的事情,包含所有关键元素。请注意,我实际上并不是在创建一个复制列表的生成器,只是将其作为一个最小的示例。

class Test():
    items = <list>

    def __init__(self):
        self.index = 0

    def __next__(self):
        if self.index >= len(self.items):
            raise StopIteration
        value = self.items[self.index]
        self.index += 1
        return value

    def reset(self):
        self.index = 0
Run Code Online (Sandbox Code Playgroud)

所以在这种情况下,我会遍历一个列表,直到它耗尽,然后下游调用将决定是重置生成器还是在耗尽后继续。但是,StopIteration由于它已被弃用,我如何在不使用的情况下启用这样的功能?使用returnhere 来提高 a的标准建议StopIteration似乎并不适用,我真的宁愿不更改下游代码来检查生成器产量Nones

那我应该在这里做什么?是StopIteration例外还是可以接受的__next__

Mar*_*ers 5

StopIteration不是被弃用,你只是误解了一些关于什么发电机。你实际上没有一个生成器,你有一个迭代器。生成器只是yield用于创建迭代器的函数。

您正在创建自己的基本迭代器实现而不使用生成器。迭代器StopIterator__next__完成时开始提升。您的代码在这里正确执行。

从Python 数据模型文档的生成器类型部分

Python 的generator提供了一种方便的方式来实现迭代器协议。如果容器对象的__iter__()方法被实现为生成器,它将自动返回一个迭代器对象(从技术上讲,一个生成器对象)提供__iter__()__next__()方法。有关生成器的更多信息可以在 yield 表达式的文档中找到。

来自同一个文档,在Iterator Types部分

iterator.__next__()
从容器中返回下一个项目。如果没有其他项目,则引发StopIteration异常。

有一个弃用,但这仅涉及StopIteration在生成器函数中使用。请参阅PEP 479 - 更改生成器内的 StopIteration 处理

此 PEP 建议对生成器进行更改:当StopIteration在生成器内被提升时,将其替换为RuntimeError. (更准确地说,当异常即将从生成器的堆栈帧中冒出时,就会发生这种情况。)由于更改是向后不兼容的,因此最初使用__future__语句引入该功能。

在生成器中,使用return会触发StopIteration异常。提高StopIteration手动实际上可以创造不明显的错误,因为由此产生的迭代器无法区分的任何消费者正确使用异常和不正确的,偶然的 StopIteration例外情况从你的产生eminating。这使得这些问题难以调试,这就是为什么它们在生成器函数中的使用在未来的 Python 版本中会发生变化。

旁注:您的实现需要iterator.__iter__()方法,它只返回self