为什么必须在类中使用__iter __()方法?

时间:2016-08-21 13:14:48

标签: python

iter 的作用究竟是什么?请考虑以下代码块:

class Reverse:
    def __init__(self,data):
        self.data = data
        self.index = len(data)
    def __iter__(self):
        return self
    def next(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]

省略 iter (自我)并重写:

class Reverse2:
    def __init__(self,data):
        self.data = data
        self.index = len(data)
    def next(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]

然后:

x = [1,2,3]
y = Reverse(x)
z = Reverse2(x)
y.next()
>>> 3
y.next()
>>> 2
y.next()
>>> 1
z.next()
>>> 3
z.next()
>>> 2
z.next()
>>> 1

无论我是否包含 iter (),这些类的行为方式都相同,那么我为什么要首先包含它呢?如果我的问题不清楚,我很抱歉 - 我根本不知道如何以更清晰的方式陈述它......

2 个答案:

答案 0 :(得分:1)

当需要迭代器时,总是调用__iter__方法,例如通过明确调用iterfor - 循环或创建列表list(xy)

所以你不能在所有这些背景下使用你的第二课Reverse2

>>> list(Reverse("abc"))
['c', 'b', 'a']
>>> list(Reverse2("abc"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: iteration over non-sequence

要回答评论中的问题:__iter__ - 方法必须返回任何带有__next__ - 方法的迭代器或实例。只有当您的类本身是迭代器时,它才会返回self。将生成器作为迭代器返回的示例:

class Reverse3:
    def __init__(self,data):
        self.data = data
    def __iter__(self):
        # returns an generator as iterator
        for idx in range(len(self.data)-1, -1, -1):
            yield self.data[idx]

答案 1 :(得分:0)

__iter__返回iterator object,它允许将对象转换为可以通过for .. in ..迭代的容器。

迭代器对象是定义__next__方法的任何对象,如果存在则返回下一个项目,否则返回StopIteration

虽然__iter__可以返回任何这样的迭代器对象,但如果它实现了__next__方法,它可以返回自己。

例如:

class Reverse:
    def __init__(self,data):
        self.data = data
        self.index = len(data)
    def __iter__(self):
        return self
    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]

现在你可以使用in for循环:

for xx in Reverse(x):
    print xx