Python连载41-yield from详解、委派生成器

一、
1.yield from
(1)调用协程为了得到返回值,协程必须正常终止
(2)生成器正常终止会发出StopIteration异常,异常对象的value属性保存返回值。
(3)yield from从内部捕获StopIteration异常
41.1
我们举个例子

def gen():
    for c in "AB":
        yield c
#list直接用生成器作为参数
print(list(gen()))
def gen_new():
    yield from "AB"
print(list(gen_new())

41.2

解释:我们从中可以看出,两个函数最后返回的结果是一致的,可以用下面的图片来解释它们的运行过程,第二个函数增加了一个管道层,使得这个函数更加灵活;第一个函数中,list向迭代器逐一要值,然后一起输出出来;第二个函数,向管道要值,然后管道收集到所有的迭代数,然后再一并返回给list函数
41.3

2.委派生成器
(1)包含yield from表达式的生成器函数
(2)委派生成器在yield from表达式暂停,调用方可以直接把数据发给自生成器
(3)子生成器再把产出的值发给调用方
(4)子生成器在最后,解释器会抛出StopIteration,并且把返回值附加到异常对象上
举个例子:

from collections import namedtuple
ResClass = namedtuple("Res","count average")
#子生成器
def average():
    total = 0.0
    count = 0
    average = None

    while True:
        term = yield
        #None是哨兵值
        if term is None:
            break
        total += term
        count += 1
        average = total/count

    return ResClass(count,average)

#委派生成器
def grouper(storages,key):
    while True:
        #获取averager()返回的值
        storages[key] = yield from average()

#客户端代码
def abc():
    process_data = {
        "boys_2":[39.0,40.8,43.2,43.1,38.6,41.4,40.6,36.3],
        "boys_1":[1.38,1.5,1.32,1.25,1.37,1.48,1.25,1.49,1.46]
    }
    storages = {}
    for k,v in process_data.items():
        #获取协程
        coroutine = grouper(storages,k)
        #预激协程
        next(coroutine)

        #发送数据到协程
        for dt in v:
            coroutine.send(dt)

        #终止协程
        coroutine.send(None)
    print(storages)
#run
if __name__ == "__main__":
    abc()

41.4

#解释:
#1.外层for循环每次迭代会新建一个grouper实例,赋值给coroutine变量;grouper是委派生成器生成
#2.调用next(coroutine),预激委派生成器grouper,此时进入while True循环,调用子生成器average
#3.内层for循环调用coroutine.send(value),直接把值传给子生成器average,同时,当前的grouper
#4.内层循环结束后,grouper实例依旧在yield from表达式处暂停,因此,grouper函数定义体中
#5.coroutine.send(None)终止averager子生成器,子生成器抛出StopIteration异常并将返回数组
二、源码
d27_4_yield_from_and_delegate_generator.py
https://github.com/ruigege66/Python_learning/blob/master/d27_4_yield_from_and_delegate_generator.py
2.CSDN:https://blog.csdn.net/weixin_44630050(心悦君兮君不知-睿)
3.博客园:https://www.cnblogs.com/ruigege0000/
4.欢迎关注微信公众号:傅里叶变换,个人公众号,仅用于学习交流,后台回复”礼包“,获取大数据学习资料
41.5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值