深入yield-from

Python 2019-02-11 1352

转载链接:https://www.cnblogs.com/wongbingming/p/9085268.html

# 子生成器  
# yield from 后面需要加的是可迭代对象,它可以是普通的可迭代对象,也可以是迭代器,甚至是生成器。  
# yield from后面加上可迭代对象,他可以把可迭代对象里的每个元素一个一个的yield出来

# 1、调用方:调用委派生成器的客户端(调用方)代码  
# 2、委托生成器:包含yield from表达式的生成器函数  
# 3、子生成器:yield from后面加的生成器函数  
def average_gen():  
    total = 0  
    count = 0  
    average = 0  
    while True:  
        new_num = yield average  
        if new_num is None:  
            break  
        count += 1  
        total += new_num  
        average = total/count  

    # 每一次return,都意味着当前协程结束。  
    return total,count,average  

# 委托生成器,可以理解为桥梁  
# 委托生成器的作用是:在调用方与子生成器之间建立一个双向通道  
def proxy_gen():  
    while True:  
        # 只有子生成器要结束(return)了,yield from左边的变量才会被赋值,后面的代码才会执行。  
        total, count, average = yield from average_gen()  
        print("计算完毕!!\n总共传入 {} 个数值, 总和:{},平均数:{}".format(count, total, average))  

# 调用方  
def main():  
    # 所谓的双向通道是什么意思呢?  
    # **调用方可以通过send()直接发送消息给子生成器,而子生成器yield的值,也是直接返回给调用方。**  
    calc_average = proxy_gen()  
    next(calc_average)            # 预激协程,或者calc_average.send(None)  
    print(calc_average.send(10))  # 打印:10.0  
    print(calc_average.send(20))  # 打印:15.0  
    print(calc_average.send(30))  # 打印:20.0  
    # 为什么10会与20联合计算,第一步传入10后,average为10,为什么没有结束因为while True  
    calc_average.send(None)      # 结束协程  
    # 如果此处再调用calc_average.send(10),由于上一协程已经结束,将重开一协程  

if __name__ == '__main__':  
    main()  

我一直纠结于为什么send之后,程序会继续执行,其实这是一个很蠢的问题,首先程序是自上而下(在主函数中),send某个值后,程序向下执行到下一个send,由于yield是可暂停的函数,并且使用循环+yield from,可以一步到子生成器中,接着运行,当使用send(None)是才意味着协程整个结束

标签:Python

文章评论

评论列表

已有0条评论