python __iter __(迭代器和生成器)

时间:2016-04-08 00:46:52

标签: python python-2.7 python-3.x

我在python中读了一本关于ADV主题的书 作者试图解释发电机

这是他解释的例子:

class rev:
    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]
def main():
    reve = rev('zix')
    for i in reve:
        print(i)
if __name__=='__main__':
    main()

此代码的主要思想是反转生成器 输出是:

>>> 
x
i
z
>>> 

我觉得很难理解的是这部分:

    def __iter__(self):
        return self 

有人可以向我解释

3 个答案:

答案 0 :(得分:2)

当你执行for x in xs时,xs必须是可迭代的,这意味着您可以通过{{{{}>获取迭代器 1}},您可以在iter(xs)实施时执行此操作。实现xs.__iter__()需要迭代器,以便__next__()运算符可以通过调用in逐个使用它。

现在,在您的情况下

next()

在REPL中输入上述代码段。运行几次。你会感受到它。

答案 1 :(得分:1)

iterator协议由两种方法组成:

  • __iter__
  • __next__

另外,要求__iter__返回self - 所以,如果您的objiterator,那么

obj is iter(obj) is obj.__iter__()

是真的。

这是一件好事,因为它允许我们说iter = iter(obj),如果obj已经是迭代器,我们仍然拥有相同的对象。

答案 2 :(得分:0)

由于您的类为next()提供了一个实现,它会返回self,因此调用者在循环您的对象时会调用它。相反,如果您只想包装已提供__iter__next(例如列表)实现的数据结构,则可以从类中返回self.data.__iter__()。在这种情况下,调用者在执行循环或列表理解时会调用该对象上定义的next()

class rev:
    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]


class rev2:
    def __init__(self, data):
        self.data = data

    def __iter__(self):
        return self.data.__iter__()


def main():
    for i in rev('zix'):  # str doesn't provide implementation for __iter__
        print(i)
    for i in rev2(['z', 'i', 'x']):  # list does so no need to implement next
        print(i)