12

iterator

迭代器协议

迭代器是实现了__next____iter__方法的对象。

  • next: 返回容器的下一个条目
  • iter: 返回迭代器本身
#python3.5

class CountDown(object):
    def __init__(self, step):
        self.step = step

# 如果是python2.7,需要将 __next__ 方法写为 next()     
    def __next__(self):
        if self.step < 0:
            raise StopIteration
        self.step -= 1
        return self.step

    def __iter__(self):
        return self

生成器

使用yield 关键字生成一个生成器对象,该对象只有在响应next操作的时候才会运行。使用yield时,当执行next操作的时候,碰到yield,语句会直接返回,当执行下一次next操作的时候,会从上次中断的地方开始运行,yield的执行作用域是会保存的。

#python3.5
class Node(object):
    def __init__(self, value):
        self._value = value
        self._children = []
    def __repr__(self):
        return "Node {!r}".format(self._value)
    def add_child(self, node):
        self.children.append(node)
    def __iter__(self):
        return iter(self._children)
    def depth_first(self):
        yield self
        for c in self:
            yield from c.depth_first()

if __name__ == '__main__':
    root = Node(0)
    child1= Node(1)
    child2 = Node(2)
    root.add_child(child1)
    root.add_child(child2)
    child1.add_child(Node(3))
    child1.add_child(Node(4))
    child2.add_child(Node(5))

    for ch in root.depth_first():
        print(ch)

反向迭代协议

#python3.5
class CountDown(object):
    def __init__(self, start):
        self.start = start

    def __iter__(self):
        n = self.start
        while n > 0:
            yield n
            n -= 1

    def __reversed__(self):
        n = 1
        while n <= self.start:
            yield n
            n += 1

    def next(self):
        if self.start < 0:
            raise StopIteration
        else:
            self.start -= 1
            return self.start

与正向迭代不同的是,反向迭代需要实现__reversed__方法,但是正向迭代需要实现__iter__,__next__/next方法。

other