使用生成器 --實現迭代協議

weixin_33807284發表於2018-10-03

目前來看,要在物件上實現可迭代功能,最簡單的方式就是使用生成器函式。

使用示例:使用生成器函式,實現一個迭代器能夠以深度優先的模式遍歷樹的節點

class Node:
    def __init__(self, value):
        self._value = value
        self._children = []

    def __repr__(self):
        return 'Node({!r})'.format(self._value)

    def add_children(self, node):
        self._children.append(node)

    def __iter__(self):
        return iter(self._children)

    def depth_first(self):
        """
        1、首先產生出自身
        2、然後迭代每個子節點,利用子節點的depth_first()方法(通過yield from 語句)產生出其他元素
        """
        yield self
        for c in self:
            yield from c.depth_first()

root = Node(0)
child1 = Node(1)
child2 = Node(2)
root.add_children(child1)
root.add_children(child2)
child1.add_children(Node(3))
child1.add_children(Node(4))
child2.add_children(Node(5))

for ch in root.depth_first():
    print(ch)  # 深度優先
Outs:    
Node(0)
Node(1)
Node(3)
Node(4)
Node(2)
Node(5)

關於Node類:
1、Node類本身就是一個迭代器,以委託迭代的方式實現;
2、類裡面的depth_first()方法,使用生成器函式實現了以深度優先的模式遍歷樹節點的迭代器。

總結:

1、Python的迭代協議要求__iter__()返回一個特殊的迭代器物件,該物件必須實現__next__()方法,並使用StopIteration異常來通知迭代完成;
2、把迭代器以生成器的形式來定義,以此實現迭代協議非常高效。

相關文章