基于生成器编写python迭代器的最佳方法是什么
我一直在寻找一种编写基于生成器的Python迭代器的好方法。我已经找到了很多关于迭代器的教程,还有很多关于生成器和yield语句的教程,但是没有找到将两者结合在一起的教程。我已经建立了一个小的例子,并想知道是否有更好的方法来做到这一点基于生成器编写python迭代器的最佳方法是什么,python,iterator,generator,Python,Iterator,Generator,我一直在寻找一种编写基于生成器的Python迭代器的好方法。我已经找到了很多关于迭代器的教程,还有很多关于生成器和yield语句的教程,但是没有找到将两者结合在一起的教程。我已经建立了一个小的例子,并想知道是否有更好的方法来做到这一点 class myIterator : def __init__(self, n) : self.last = n self.myGen = self.myGenerator() def __iter__(sel
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
类My迭代器:
定义初始化(self,n):
self.last=n
self.myGen=self.myGenerator()
定义(自我):
返回self.myGenerator()
def next(自我):
返回self.myGen.next()
def myGenerator(自):
prev=0
fib=1
当fib
我在一个真实世界的程序中使用了这种技术,可以在
其中最复杂的部分是定义next()函数。显而易见的解决方案在每次调用时都返回第一个元素。存储一个包含生成器的实例变量是可行的,但似乎是一个难题
如果你知道一个更好的方法来做这件事或者一个很好的教程,涵盖这个主题,请让我知道
编辑:
@MartijnPieters发布的第三个示例完全解决了这个问题。在self.next中保存self.generator.next函数将提供下一个函数。我希望这能帮助其他人解决这个问题。迭代器协议由两部分组成。
\uuuu iter\uuuu
方法是最重要的方法,当您在对象上使用iter()
时,它将返回迭代器
只需将的主体替换为myGenerator
;无需提出StopIteration
:
class myIterator:
def __init__(self, n):
self.last = n
def __iter__(self):
prev = 0
fib = 1
while fib < self.last:
res = fib
yield res
fib += prev
prev = res
或者可以重用生成器的.next()
方法:
class myIterator:
def __init__(self, n):
self.last = n
self.next = self.myGenerator().next # Use the generator `.next`
def __iter__(self):
return self
def myGenerator(self):
prev = 0
fib = 1
while fib < self.last:
res = fib
yield res
fib += prev
prev = res
类My迭代器:
定义初始化(self,n):
self.last=n
self.next=self.myGenerator().next#使用生成器`.next`
定义(自我):
回归自我
def myGenerator(自):
prev=0
fib=1
当fib
生成器已经是迭代器了。无需对其进行包装:
>>> def gen():
... yield 1
... yield 2
... yield 3
...
>>>
>>> a = gen()
>>> dir(a)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'next', 'send', 'throw']
>>> ai = a.__iter__()
>>> ai
<generator object gen at 0x542f2d4>
>>> a
<generator object gen at 0x542f2d4>
>>> a.next()
1
>>> a.next()
2
>>> a.next()
3
>>> a.next()
Traceback (most recent call last):
File "<string>", line 1, in <module>
StopIteration
>>def gen():
... 收益率1
... 收益率2
... 收益率3
...
>>>
>>>a=gen()
>>>处长(a)
“UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU u'、uu str_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
>>>ai=a.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()
>>>哎
>>>a
>>>a.下一步()
1.
>>>a.下一步()
2.
>>>a.下一步()
3.
>>>a.下一步()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
停止迭代
为什么不返回self.myGen
?谢谢。这可能行得通,但它仍然涉及到我希望避免的混乱。谢谢你,这正是我所希望的。注意,在Python3中,迭代器需要一个\uuuuuuuuuuuuuuuuuuuuu
方法(而不仅仅是next
)和iterator。next()
不再受支持(应该使用next(迭代器)
)。第一个示例提供了基于生成器的迭代器,但不包括next()功能。在第一个例子中,\uu iter\uu
本身就是生成器,生成器提供自己的.next()
方法<代码>\uuuu iter\uuuu
应该返回迭代器,而生成器符合该要求。在第二种形式中,我们返回self
,然后才需要显式定义.next()
方法。这正是我所希望的,但当我尝试使用next()时,它告诉我“myIterator实例没有属性'next'”。实际上,在现实世界中,有理由将其包装到类中。当我开始这个项目时,我使用了一个生成器,它变得有点混乱,所以我决定使用一个类来包装它的其他部分。我将再次尝试“仅生成器”方法thanksWell,如果您认为需要包装生成器,您可能需要告诉我们更多关于您的用例的信息。用例将文件解析为SQL语句。有相当多的设置,我肯定需要使用yield,因为结果是从for循环的中间返回的。但我将再次尝试仅使用生成器的版本谢谢
>>> def gen():
... yield 1
... yield 2
... yield 3
...
>>>
>>> a = gen()
>>> dir(a)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'next', 'send', 'throw']
>>> ai = a.__iter__()
>>> ai
<generator object gen at 0x542f2d4>
>>> a
<generator object gen at 0x542f2d4>
>>> a.next()
1
>>> a.next()
2
>>> a.next()
3
>>> a.next()
Traceback (most recent call last):
File "<string>", line 1, in <module>
StopIteration