yield from和yield虽然只有一字之差,但是,两者在协程里面扮演着完全不一样的角色,yield可以作为产出,让步来理解,当然,在实际中确实也扮演着这样的目的,在一个包含yield的等式里面,我们以yield作为分界线,yield右边的等式,为产出,即协程在这个地方停留,然后产出这个值,如果在IDE里面的话,执行这个协程,并且打印的话,能打印出来的结果。yield左边的值是send进入的值,即是你传入的值。对于yield from,我将借用《流畅的Python》里面的一个算例子和大家分享。
from collections import namedtuple
Result=namedtuple('Result','count average')
def average():
total=0
count=0
average= None
while True:
term=yield
if term is None:
break
total += term
count +=1
average=total/count
return Result(count,average)
def grouper(results,key):
while True:
results[key]=yield from average()
def main(data):
results={}
for key,values in data.items():
group=grouper(results,key)
next(group)
for value in values:
group.send(value)
group.send(None)
report(results)
def report(results):
for key,result in sorted(results.items()):
group,unit=key.split(';')
print('{:2} {:5} averaging {:.2f}{}'.format(result.count,group,result.average,unit))
data={
'girls;kg':[49,34,28,42,45,41.7,44.5,38,40.6,44.5],
'girls;m':[1.6,1.4,1.45,1.3,1.41,1.39,1.6,1.56,1.4,1.5],
'boys;kg':[55,45,56,37,57],
'boys;m':[1.6,1.5,1.57,1.67,1.7]
}
这个里面,我们主要看main里面的那一块,首先确认,传入的data是一个字典key有4个值,value是一个列表,
然后先把result定义为一个空的字典,继而在for循环里面,将result和key传给grouper,这是一个委派生成器,在我理解来说,就是一个连接后面一个子生成器的桥梁,并且处理一个stopiteration的异常;但是这个也是result from放光的地方,注意看grouper的result from,右边是一个生成器,左边是一个变量(姑且这么叫),然后呢,我们回到main,之后main函数激活了grouper,再使用一个for 循环,将data里面的值send出去,这个时候,你可能不知道会将值send到什么位置去,这一步较好就是让值进入yield from后面的那个子生成器中去,然后再通过子生成 器一些列操作,最后接收了子生成器return的值,当然,当值迭代完成之后,我们还要将该次子生成器结束。其实,这个其中,yield from让数据传输变得非常的简单,方便。还有很多这个使用的技巧,希望我们以后一起探讨。