我已就此主题的类似问题进行过研究,但没有发现重复。
如果对象实现__iter__
协议,则说明对象是 iterable 。
iterator.__iter__()
: 返回迭代器对象本身。这是允许容器和迭代器与for和in语句一起使用所必需的。
iterator.__next__()
: 从容器中返回下一个项目。如果没有其他项目,请提高StopIteration例外。
根据我的理解,这适用于所有迭代器对象。我遇到过一个实现二叉树容器的代码。容器只有__iter__
,节点对象也驻留在其中。
Node对象的__iter__
实现返回生成器。它产生了对象,似乎做了所有逻辑,没有__next__
的实现。
此代码的实际工作原理如何?它似乎只是作为常规迭代器运行,但是这个没有__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'>
答案 0 :(得分:7)
您的__iter__
方法是generator function,因为它在函数体中使用了yield
。调用时,生成器函数返回生成器对象。 该对象具有__next__
方法。
您的Node
本身不是迭代器。它只是一个可迭代的对象;当你调用它的__iter__
方法时,一个可迭代对象返回一个新的迭代器实例,这就是这里发生的事情。
答案 1 :(得分:3)
生成器非常有__next__
方法。你自己不要实现它。 A&#34;功能&#34;使用yield
语句不会运行您的代码。它返回一个运行代码的对象。该对象具有__next__
方法。
您可能还需要注意,还有另一种使对象可迭代的机制:提供__len__
和__getitem__
方法。在这种情况下,迭代将在从零到len-1的索引上发生。