我一直在寻找一种好方法来编写基于生成器的Python迭代器。我找到了很多关于迭代器主题的教程,也有很多关于生成器和yield语句的教程,但是没有找到将两者结合起来的教程。我已经建立了一个很好的例子,想知道是否有更好的方法来实现这一点。在
class myIterator :
def __init__(self, n) :
self.last = n
self.myGen = self.myGenerator()
def __iter__(self) :
return self.myGenerator()
def next(self) :
return self.myGen.next()
def myGenerator(self) :
prev = 0
fib = 1
while fib < self.last :
res = fib
yield res
fib = fib + prev
prev = res
raise StopIteration
我在一个实际的程序中使用了这种技术,可以在SQLStatements.py in my Github repository找到它
其中最令人费解的部分是定义next()函数。显而易见的解决方案每次被调用时都返回第一个元素。存储包含生成器的实例变量是可行的,但似乎是一种浪费。在
如果你知道一个更好的方法来做这个或一个好的教程,涵盖这个主题,请让我知道。在
编辑: @MartijnPieters发布的第三个例子完全解决了这个问题。保存self.generator.next函数自我。下一个提供下一个函数。我希望这能帮助其他人解决这个问题。在
迭代器协议由两部分组成。
__iter__
方法是最重要的方法,当您在一个对象上使用iter()
时,它应该返回迭代器。在只需将
__iter__
的主体替换为myGenerator
;无需提升StopIteration
:现在
iter(myIterator(10))
是一个迭代器,有一个.next()
方法。在如果您希望您的类直接用作迭代器,则需要
__iter__
来返回self
,并提供一个.next()
方法。在一个
.next()
方法为每个函数体生成一个元素(并使用return somevalue
)。生成器只是一个使用yield
的函数,实际上,这样的方法本身为您实现了迭代器协议(包括.next()
)。在如果要使用
^{pr2}$.next()
,它看起来应该是这样的:或您可以重用生成器的
.next()
方法:生成器已经是一个迭代器。无需包装:
相关问题 更多 >
编程相关推荐