Python进阶编程:编写更高效、优雅的Python代码
上QQ阅读APP看书,第一时间看更新

4.1.2 代理迭代

自定义一个容器对象,其中包含列表、元组或其他可迭代对象。现在,我们直接在该自定义容器对象上执行迭代操作。

我们先定义一个__iter__()方法,将迭代操作代理到容器内部的对象上,代码(proxy_iter_exp.py)如下:


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

    def __repr__(self):
        return f'Node({self._value})'

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

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


if __name__ == '__main__':
    root = Node(0)
    child1 = Node(1)
    child2 = Node(2)
    root.add_child(child1)
    root.add_child(child2)
    for ch in root:
        print(f'child is:{ch}')

执行py文件,输出结果如下:


child is:Node(1)
child is:Node(2)

在上述示例代码中,__iter__()方法只是简单地将迭代请求传递给内部的_children属性。

Python的迭代器协议需要__iter__()方法返回一个实现__next__()方法的迭代器对象。如果只是迭代遍历其他容器的内容,无须担心底层是怎样实现的,只需传递迭代请求即可。

这里iter()函数的使用简化了代码,iter(s)只是简单地通过调用s.__iter__()方法来返回对应的迭代器对象,与len(s)调用s.__len__()原理是一样的。