yield from 问题

来源:12-8 生成器进阶-yield from-1

慕妹7002893

2020-09-04

sale_data = {
    "95#": [150, 66, 523, 452],
    "92#": [200, 452, 125, 689, 54],
    "0#": [212, 548, 345]
}
final_res = {}


def sales_num(product_name):
    total = 0
    numbers = []

    while True:
        x = yield
        if not x:
            break
        print(product_name + "的销量为:{}".format(x))
        total += x
        numbers.append(x)

    return total, numbers


def middleware(product_name):
    final_res[product_name] = yield from sales_num(product_name)
    print(product_name + "统计完成!!!!")


def main():
    global final_res, sale_data
    for k, v in sale_data.items():
        print(k, "开始统计")
        m = middleware(k)
        m.send(None)  # 预激middleware委托生成器质性到yield from 处
        for value in v:
            m.send(value)

        m.send(None)
    print("统计结果为:", final_res)


if __name__ == '__main__':
    main()

运行结果:

95# 开始统计
95#的销量为:150
95#的销量为:66
95#的销量为:523
95#的销量为:452
95#统计完成!!!!
Traceback (most recent call last):
  File "C:/Users/Administrator/Desktop/python-test/code_97/chapter12/my_yield_from_test.py", line 66, in <module>
    main()
  File "C:/Users/Administrator/Desktop/python-test/code_97/chapter12/my_yield_from_test.py", line 61, in main
    m.send(None)
StopIteration

写回答

2回答

bobby

2020-09-06

如果把while True去掉的话 在调用方send(None)之后 子生成器结束后会return结果到委托生成器的final_res[product_name]这个变量上,但是在调用方send(None)后并没有接收到yield返回的值,它会触发StopIteration 。
while True 使得委托生成器再进入到新的子生成器中,并在yield from sales_num(product_name)处暂停返回给调用方。这样就不会引发异常,其实不用while True 在委托生成器的最后添加一个yield也是可以的

0
0

慕妹7002893

提问者

2020-09-04

已经解决  middle 没有写while Ture  , 但是没有弄懂为什么要写while Ture循环? 老师 可以解下惑吗?

0
0

Python3高级核心技术97讲,高级进阶的必学课程

socket编程/多线程/多进程/线程池/asyncio并发编程/协程和异步IO

2121 学习 · 551 问题

查看课程