这一篇日志主要是参考Python 3: Using “yield from” in Generators。
上一篇博文介绍了yield
的使用,现在在写一个例子:
class Node:
def __init__(self,value):
self.left = []
self.value = value
self.right = []
def node_iterate(self):
for value in self.child_iterate(self.left):
v = yield value
print(‘left v is %s‘ % v)
v = yield self.value
for value in self.child_iterate(self.right):
v = yield value
print(‘right v is %s‘ %s)
def child_iterate(self,nodes):
for node in nodes:
input_value = yield node.value
print(‘input value is %s‘ % input_value)
def main():
root = Node(0)
root.left = [Node(i) for i in [1,2,3]]
root.right = [Node(i) for i in [4,5,6]]
it = root.node_iterate()
total = it.send(None)
while True:
try:
ans = it.send(total)
total += ans
except StopIteration:
break
else:
print(‘ans is %s‘ % ans)
print(‘total is %s‘ % total)
if __name__ == ‘__main__‘:
main()
运行上面的代码:
发现函数child_iterate()
中的print(‘input_value is %s‘ % input_value)
中输出的一直是’input_value is None’。以为在执行到input_value = yield value
时,方法直接被yield
了,下次直接从下一句语句开始执行。
因此,如果想要利用input_value
的值做运算的话,是不可以的。
但是在node_iterate()
中可以利用v = yield value
的值做运算。但是观察v
的值,它等于root.send(total)
中传入的total
的值。而在while
语句中的ans
的值,才是想要的值——节点的值。
在node_iterate()
中v
的值不是需要的值,加上这一句显然是多余的。此时就可以用yield from
语法了。修改node_iterate()
中的代码:
def node_iterate(self):
yield from self.child_iterate(self.left)
input_value = yield self.value
yield from self.child_iterate(self.right)
保存后在运行代码,会发现child_iterate()
中的input_value
有值了:
如果只想用yield
,可以使用send()
和next()
方法,来控制生成器的运行。
还可以继续修改代码:
class Node:
def __init__(self,value):
self.left = []
self.value = value
self.right = []
def process(self):
v = yield self.value
print(‘v is %s‘ % v)
def child_iterate(self,nodes):
for node in nodes:
yield from node.process()
def node_iterate(self):
yield from self.child_iterate(self.left)
self.process()
yield from self.child_iterate(self.right)
······
代码是不是看起来干净多了?使用yield from
可以写更少的代码。
自己对yield
和yield from
还不是很熟,等到很熟的时候,好好的终结一下吧,现在先用着在说。因为如果asyncio
、aiohttp
和aiomysql
这三个库,代码不可能离开yield from
。
加油吧!
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/mr_zys/article/details/47427701