我试图编写一个我自己的简单倒计时迭代器,我实现了一个__iter__()
函数和相应的__next__()
来支持迭代器。我在里面使用了yield
函数__next__()
函数每次迭代对象时返回一个新值。
当我使用yield
时,与使用return
语句相比,代码在无限循环中进行。
以下是我的代码:
class MyIterator():
def __init__(self,value):
self.value = value
def __iter__(self):
return self
def __next__(self):
print("In the next function")
if self.value > 0:
yield self.value
self.value -= 1
else:
raise StopIteration("Failed to proceed to the next step")
if __name__ == '__main__':
myIt = MyIterator(10)
for i in myIt:
print(i)
O / P如下:
<generator object __next__ at 0x101181990>
<generator object __next__ at 0x1011818e0>
<generator object __next__ at 0x101181990>
<generator object __next__ at 0x1011818e0>
and so on for infinite times....
答案 0 :(得分:2)
您的__next__
方法不本身应该是生成器。将yield
替换为return
:
def __next__(self):
print("In the next function")
if self.value > 0:
return_value = self.value
self.value -= 1
return return_value
else:
raise StopIteration("Failed to proceed to the next step")
请注意,在确定要返回的内容后,您仍需要减少self.value
,因此请使用单独的return_value
变量。
任何带有yield
的函数(或方法)在调用时都会生成一个生成器对象,然后该生成器就是可迭代的。然后,这样的对象具有__iter__
方法,该方法返回self
和__next__
方法,该方法在调用时将生成下一个值。这就是为什么每次调用<generator object __next__ at 0x1011818e0>
时都会看到正在打印的__next__
对象。
但是,为了使您的对象成为可迭代的,您的__next__
方法应该返回序列中的下一个值。它会被重复调用,直到它引发StopIteration
。这与使用yield
不同,它应该立即返回,而不是推迟到以后!
演示:
>>> class MyIterator():
... def __init__(self,value):
... self.value = value
... def __iter__(self):
... return self
... def __next__(self):
... print("In the next function")
... if self.value > 0:
... return_value = self.value
... self.value -= 1
... return return_value
... else:
... raise StopIteration("Failed to proceed to the next step")
...
>>> myIt = MyIterator(10)
>>> for i in myIt:
... print(i)
...
In the next function
10
In the next function
9
In the next function
8
In the next function
7
In the next function
6
In the next function
5
In the next function
4
In the next function
3
In the next function
2
In the next function
1
In the next function
如果你想使用生成器函数,请使__iter__
生成器,并使用循环:
class MyIterator():
def __init__(self,value):
self.value = value
def __iter__(self):
value = self.value
while value > 0:
yield value
value -= 1
但是,这会使您的MyIterator
类成为可迭代的,而不是迭代器。相反,每次使用for
循环时,都会创建 new 迭代器(__iter__
生成器对象),然后迭代。使用__next__
使您的对象成为只能在上迭代的迭代器。
答案 1 :(得分:2)
这里有点混乱。当您使用 yield 时,您不需要创建迭代器类。生成器已经是迭代器。
所以,将 yield 更改为 return ,它会做你想做的事: - )
此外,您需要在 self.value
之前更新return
。这是固定代码的样子:
class MyIterator():
def __init__(self,value):
self.value = value
def __iter__(self):
return self
def __next__(self):
print("In the next function")
value = self.value
if value > 0:
self.value -= 1
return value
else:
raise StopIteration("Failed to proceed to the next step")
以下是如何使用生成器执行相同的操作:
def my_iterator(value):
while value > 0:
yield value
value -= 1
正如您所看到的,生成器使程序员的生活变得更加容易: - )