>[success] # 生成器 yield ~~~ 1.函数中出现了yield 语句就会将其转换成一个生成器,生成器只有在相应的时候才会执行 ~~~ >[danger] ##### 仿写一个range 函数 ~~~ def frange(start, stop, increment=1): x = start while x < stop: yield x x += increment for i in frange(1,10): print(i) ~~~ >[danger] ##### 机制说明案例 ~~~ 1.返现直接打印 并不会执行函数,只会打印内存地址 2.当使用迭代器的时候就会重新打印出数据,执行代码,for 同理 ~~~ ~~~ def countdown(n): print('startin to count from', n) while n>0: yield n n -=1 print('Done!') c = countdown(3) print(c) print(next(c)) 打印结果: <generator object countdown at 0x000002038E5D6E60> startin to count from 3 3 ~~~ >[danger] ##### 类似递归机制,获取每一个根对象和根对象内容 ~~~ 1.对于简单的迭代器,yield from iterable本质上等于for item in iterable: yield item 2.简单的理解会把能迭代的对象继续迭代 3.>>> def g(x): ... yield from range(x, 0, -1) ... yield from range(x) ... >>> list(g(5)) [5, 4, 3, 2, 1, 0, 1, 2, 3, 4] 上面的代码直接用 yield 的话只会打印出 range(x, 0, -1) 不会讲内容迭代 ~~~ ~~~ class Node: def __init__(self, value): self._value = value self._children = [] def __repr__(self): return 'Node({!r})'.format(self._value) def add_children(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_children(child1) root.add_children(child2) child1.add_children(Node(3)) for ch in root.depth_first(): print(ch) 打印结果: Node(0) Node(1) Node(3) Node(2) ~~~