一个简单的Python迭代器进入无限循环

Apa*_*nti 3 python iterator yield generator

我试图编写自己的简单倒计时迭代器,我实现了一个__iter__()函数和相应的函数__next__()来支持迭代器。我在函数yield内部使用了一个函数__next__(),以便每次迭代对象时返回一个新值。与using 语句相比,当我使用 时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)
Run Code Online (Sandbox Code Playgroud)

其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....
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 6

您的__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")
Run Code Online (Sandbox Code Playgroud)

请注意,在确定要返回的内容后,您仍然需要减少self.value,因此使用单独的return_value变量。

任何包含其中的函数(或方法)yield在调用时都会生成一个生成器对象,并且该生成器就是可迭代的。这样的对象有一个__iter__返回的方法self和一个__next__在调用时生成下一个值的方法。这就是为什么<generator object __next__ at 0x1011818e0>每次__next__调用时都会看到正在打印的对象。

但是,为了使您的对象本身成为可迭代对象,您的__next__方法应该返回序列中的下一个值。它将被重复调用,直到引发StopIteration。这与 using 不同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
Run Code Online (Sandbox Code Playgroud)

如果您想使用生成器函数,请创建__iter__生成器并使用循环:

class MyIterator():
    def __init__(self,value):
        self.value = value
    def __iter__(self):
        value = self.value
        while value > 0:
            yield value
            value -= 1
Run Code Online (Sandbox Code Playgroud)

但是,这使您的MyIterator类成为可迭代的,而不是迭代器。相反,每次使用循环时都会创建for一个新的__iter__迭代器(生成器对象),然后对其进行迭代。使用__next__使您的对象成为只能迭代一次的迭代器。