请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于您的例子代码的问题

老师我想问一下,您的那个例子,

def middle(key):
    while True:
        final_result[key] = yield from sales_sum(key)
        print(key + '销量统计完成',final_result)

这个middle函数为什么要加while True呢?
我试了,如果不加while True,在main()方法里第二次m.send(None)时,就会抛出StopIteration
但是如果我不在middle函数里加while True,我也可以这么写,我catch住第二个send(None)就能继续执行
def main():
data_sets = {
‘bobby牌面膜’:[1200, 1500, 3000],
‘bobby牌手机’:[28,55,98,108],
‘bobby牌大衣’:[280,560,778,70]
}

for key, data_set in data_sets.items():
    print('start key:', key)
    m = middle(key)
    m.send(None)
    for value in data_set:
        m.send(value)
    try:
        m.send(None)
    except StopIteration as e:
        pass
print('final_result:', final_result)

我想问一下这个为什么sales_sum退出的时候会往调用main()方法里抛一个StopIteration,但您在中继函数里加个while True就不抛了

正在回答 回答被采纳积分+3

1回答

bobby 2024-12-27 11:06:09

关键点解析

  1. sales_sum 是一个生成器:
    sales_sum(key) 执行完毕时,根据生成器的设计规范,它会抛出一个 StopIteration 异常,表示生成器已经结束执行并返回了结果。

  2. yield from 的作用:

    在你的代码中:

    python复制代码final_result[key] = yield from sales_sum(key)

    sales_sum 结束时,yield from 捕获到 StopIteration,把其中的返回值提取出来,赋值给 final_result[key]。但是,middle 本身在执行完这一行代码后,也会结束,并抛出 StopIteration

  • yield from 的本质是简化生成器的嵌套调用。

  • yield from 调用一个子生成器(这里是 sales_sum(key)),它会自动处理子生成器的 StopIteration 异常,并把子生成器返回的值赋给 yield from 表达式。

为什么加了 while True 不会抛出 StopIteration
加了 while True 后,middle 函数在处理完一个 sales_sum(key) 后,会继续等待下一个调用。即使子生成器 sales_sum(key) 完成并返回结果,middle 还会继续运行,而不会自己结束。这种设计可以让 middle 函数持续处理多次输入,而无需每次都重新启动它。

不加 while True 的情况:
如果没有 while Truemiddle 在第一次 yield from 完成后就会结束,直接抛出 StopIteration。这会导致在 main() 中,第二次调用 m.send(None) 时尝试操作一个已经关闭的生成器,进而引发异常。

两种解决方案对比

方案 1: 加 while True

python复制代码def middle(key):    while True:
        final_result[key] = yield from sales_sum(key)        print(key + '销量统计完成', final_result)
  • 优点:

    • 生成器可以持续运行,不需要每次都重新初始化。

    • 程序逻辑更加清晰,不需要显式处理 StopIteration

  • 适用场景:

    • 需要处理多个数据集时,这种方法更加简洁高效。

方案 2: 在外部捕获 StopIteration

python复制代码def main():    for key, data_set in data_sets.items():        print('start key:', key)
        m = middle(key)
        m.send(None)  # 初始化
        for value in data_set:
            m.send(value)        try:
            m.send(None)  # 结束处理
        except StopIteration:            pass
  • 优点:

    • 不依赖于生成器的无限循环,控制更加显式。

  • 缺点:

    • 每次处理一个数据集时都需要重新创建生成器。

    • 程序逻辑稍显冗长,需要显式处理 StopIteration

为什么要优先使用 while True

使用 while True 是一种更加通用的设计模式,适合那些希望生成器能够持续运行的场景。它让 middle 函数具备「中继」的能力,可以不断处理新任务,而不需要反复创建生成器。这种设计尤其在事件驱动或协程编程中非常常见,比如处理数据流或异步任务队列。

如果你的应用场景中,middle 只需处理一次调用,那么不加 while True 的写法也完全可行,只是实现上需要多一点控制逻辑。


0 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号