apache2 service
我认为列表是一个可以迭代它的对象,为什么要使用class Node:
def __init__(self, value):
self._value = value
self._children = []
def __repr__(self):
return 'Node({!r})'.format(self._value)
def add_child(self, node):
self._children.append(node)
def __iter__(self):
return iter(self._children)
def depth_first(self):
yield self
for c in self:
yield from c.depth_first()
if __name__ == '__main__':
root = Node(0)
child1 = Node(1)
child2 = Node(2)
root.add_child(child1)
root.add_child(child2)
child1.add_child(Node(3))
child1.add_child(Node(4))
child2.add_child(Node(5))
for a in root.depth_first():
print(a)
# Outputs Node(0), Node(1), Node(3), Node(4), Node(2), Node(5)
?我是python中的新手,所以这看起来很奇怪。
答案 0 :(得分:1)
因为返回self._children
返回一个list
对象,它不作为迭代器工作,请记住, iterators 按顺序实现__next__
方法在迭代期间提供项目:
>>> next(list()) # doesn't implement a __next__ method
TypeError: 'list' object is not an iterator
list
是 iterable ,它们可以迭代,因为调用iter
会返回迭代器,但是,{{1它们本身不是迭代器 - 这些的细分可以在this Question的最佳答案中找到。
每次调用list
时,列表__iter__
方法都会返回自定义的新list_iterator
对象:
__iter__
并且,通过这样做,多次支持迭代,list().__iter__()
Out[93]: <list_iterator at 0x7efe7802d748>
对象实现了所需的list_iterator
方法。
调用并返回__next__
就可以了,返回列表迭代器并省去了必须实现iter
的麻烦。
解决有关__next__
原因的评论,好吧,因为它基本上是在做同样的事情。 for循环基本上发生了什么:
for c in self._children
意思是,it = iter(self._children) # returns the list iterator
while True:
try:
i = next(it)
<loop body>
except StopIteration:
break
在列表对象上再次被调用,并由iter
循环用于for
次调用。
答案 1 :(得分:0)
每个可迭代对象都实现了一个返回自身的 iter ()函数。 iter(obj)调用obj。 iter (),这与在示例中返回列表对象相同。