• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
孙龙 程序员
少时总觉为人易,华年方知立业难
博客园    首页    新随笔    联系   管理    订阅  订阅
协程之生成器yield from

yield from 你知道做什么那些事情吗?

帮我们迭代:

#python3.3新加了yield from语法
from itertools import chain

my_list = [1,2,3]
my_dict = {
    "sunlong001":"http://baidu1.com",
    "sunlong002":"http://www.baidu2.com",
}

def my_chain(*args, **kwargs):
    for my_iterable in args:
        # yield from my_iterable
        for value in my_iterable:
            yield value

for value in my_chain(my_list, my_dict, range(5,10)):
    print(value)

 

yield from my_iterable等价于:
for value in my_iterable: 
yield value

 让协程返回值

#让协程返回值
#定义一个求平均值的协程
from  collections  import namedtuple
Result = namedtuple('Result','cunt average')
def averager():
    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)

coro_avg = averager()
coro_avg.send(None)
coro_avg.send(10)
coro_avg.send(20)
coro_avg.send(9)
# coro_avg.send(None)

try:
    coro_avg.send(None)
except StopIteration as exc:
    result = exc.value

print(result)

 

yield from的主要功能是打开双向通道,把最外层的调用方法与最内层的子生成器连接起来,这样二者可以直接发送和产出值,还可以直接传入异常,而不用在位于中间的协程中添加大量处理异常的代码,有了这个机构,

协程可以通过以前不可能的方式委托职责

委派生成器;

子生成器;

委派生成器在yield from 表达式处暂停时,调用放可以直接把数据发给子生成器,子生成器再把产出的值发给调用方,子生成其返回之后,解释器会抛出StopIteration异常,并把返回值附加到异常对象上,此时委派生成器会恢复

 

#让协程返回值
#定义一个求平均值的协程
from  collections  import namedtuple
Result = namedtuple('Result','cunt average')

#子生成器
def averager():
    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 averager()


#客户端代码 调用方
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)
    print(results)

data  = {
    'girls;kg':
        [40.9,38.5,42.2,45.2,41.7,44.5,38.0],
    'girls:m':
    [1.6,1.51,1.3,1.41,1.39,1.33,1.46],
}

if __name__ == '__main__':
    main(data)

#输出结果
# {'girls;kg': Result(cunt=7, average=41.57142857142857), 'girls:m': Result(cunt=7, average=1.4285714285714286)}

 

本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/articles/9494420.html

posted on 2018-08-17 17:19  孙龙-程序员  阅读(133)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3