代码之家  ›  专栏  ›  技术社区  ›  Chen A.

如何在没有next的情况下迭代iterable对象?

  •  5
  • Chen A.  · 技术社区  · 8 年前

    据说,物体是 如果它实现了 __iter__

    iterator.__iter__() : 返回迭代器对象本身。这是允许容器和迭代器与for和in语句一起使用所必需的。

    iterator.__next__() 从容器中退回下一个项目。如果没有其他项,则引发StopIteration异常。

    据我所知,这适用于所有人 迭代器对象 . 我遇到了一个实现二叉树容器的代码。容器只有 节点对象也驻留在其中。

    这个 节点对象的实现返回一个 发电机 . 它产生了对象,并且似乎 ,没有实现 __next__

    这段代码实际上是如何工作的?它似乎就像一个普通的 迭代器 __下一个__ . 当然,如果我手动操作 iter(obj) 然后 next(obj) 它起作用了。以下是代码片段:

    class BinaryCont(object):
    
        def __init__(self):
            self.root = None
            self.size = 0
    
        def __iter__(self):
    
            class EmptyIter():
                def next(self):
                    raise StopIteration
    
            if self.root:
                return self.root.__iter__()
            return EmptyIter()
    
    class Node(object):
    
        def __init__(self, val, left=None, right=None):
            self.val = val
            self.left = left
            self.right = right
    
        def __iter__(self):
            if self.has_left_child():
                for child in self.left:
                    yield child
    
            yield self.val
    
            if self.has_right_child():
                for child in self.right:
                    yield child
    

    运行代码的示例

    bt = BinaryCont()
    bt.insert(5)
    bt.insert(3)
    bt.insert(7)
    for node in bt:
        print node
    
    3
    5
    7
    
    it = iter(bt)
    type(it)
    <type 'generator'>
    
    2 回复  |  直到 8 年前
        1
  •  9
  •   Martijn Pieters    8 年前

    你的 __iter__ generator function yield 在函数体中。调用生成器函数时,返回生成器对象。它是 那个物体 这有一个 __next__

    你的 Node 可迭代的 __iter__

        2
  •  3
  •   Chris    8 年前

    发电机确实有一个 __next__ 方法你只是没有亲自实施。带有 yield __下一个__

    您可能还需要注意,还有另一种机制可以使对象可访问:提供 __len__ __getitem__ 方法。在这种情况下,将在从零到len-1的索引上进行迭代。