【问题标题】:How an iterable object is iterated without next?没有下一个可迭代对象如何迭代?
【发布时间】:2017-10-02 19:50:50
【问题描述】:

我对这个主题的类似问题进行了研究,但没有找到重复项。

如果一个对象实现了__iter__协议,那么它就是可迭代的。

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

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

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

Node 对象的__iter__ 实现返回一个生成器。它产生对象并且似乎完成了所有逻辑,但没有实现__next__

这段代码实际上是如何工作的?它看起来就像一个普通的迭代器,但是这个没有__next__。当然,如果我手动执行 iter(obj) 然后 next(obj) 它可以工作。这是代码sn-p:

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'>

【问题讨论】:

    标签: python iterator


    【解决方案1】:

    您的__iter__ 方法是generator function,因为它在函数体中使用yield。生成器函数在调用时会返回一个生成器对象。 那个对象有一个__next__ 方法。

    您的Node 本身不是迭代器。它只是一个 iterable 对象;当您调用 __iter__ 方法时,可迭代对象返回一个新的迭代器实例,这就是这里发生的情况。

    【讨论】:

    • 在阅读了您的答案和 generator function 文档后,我更加清楚了。非常感谢
    【解决方案2】:

    生成器确实有一个__next__ 方法。你只是不自己实现它。带有yield 语句的“函数”不会运行您的代码。它返回一个运行您的代码的对象。该对象有一个__next__ 方法。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-03
      • 2023-03-07
      • 2019-12-03
      • 1970-01-01
      • 1970-01-01
      • 2021-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多