Python 不确定为什么停止迭代是';t由";收益来自;

Python 不确定为什么停止迭代是';t由";收益来自;,python,generator,coroutine,yield-from,Python,Generator,Coroutine,Yield From,查看“Fluent Python”一书中的以下示例代码,其中解释了yield from的“双向隧道”功能,我有以下问题 从集合导入namedtuple 结果=名称整数('Result','count average') #子生成器 def averager():# 总计=0.0 计数=0 平均值=无 尽管如此: 期限=收益率 如果术语为“无”: 打破 总数+=期限 计数+=1 平均数=总数/计数 返回结果(计数、平均值)# #授权生成器 def grouper(结果,关键):# 尽管如此: 结果

查看“Fluent Python”一书中的以下示例代码,其中解释了
yield from
的“双向隧道”功能,我有以下问题

从集合导入namedtuple
结果=名称整数('Result','count average')
#子生成器
def averager():#
总计=0.0
计数=0
平均值=无
尽管如此:
期限=收益率
如果术语为“无”:
打破
总数+=期限
计数+=1
平均数=总数/计数
返回结果(计数、平均值)#
#授权生成器
def grouper(结果,关键):#
尽管如此:
结果[关键]=来自averager()的产量
#客户端代码,也称为调用者
def主(数据):#
结果={}
对于键,data.items()中的值:
组=石斑鱼(结果,关键点)#
下一组#
对于值中的值:
组发送(值)#
组。发送(无)#重要!
印刷品(“包装石斑鱼”)
打印(结果)
数据={
“女孩;kg”:
[40.9, 38.5, 44.3, 42.2, 45.2, 41.7, 44.5, 38.0, 40.6, 44.5],
“女孩;m”:
[1.6, 1.51, 1.4, 1.3, 1.41, 1.39, 1.33, 1.46, 1.45, 1.43],
“男孩;kg”:
[39.0, 40.8, 43.2, 40.8, 43.1, 38.6, 41.4, 40.6, 36.3],
“男孩们;m”:
[1.38, 1.5, 1.32, 1.25, 1.37, 1.48, 1.25, 1.49, 1.46],
}
当我用下面的委托生成器替换上面的委托生成器时,为什么会出现
StopIteration
异常

def grouper(结果,键):
结果[关键]=平均值的收益率()
从我到目前为止所了解到的情况来看,从理论上讲,删除
而不是True
应该可以
group.send(None)
将导致
averager()
corroutine
中断
并返回
结果(…)
,该结果将传递给委派生成器。然后委派生成器将通过将
结果(…)
分配给
结果[key]
来完成

但现在发生的是以下情况

Traceback (mostrecent call last):
  File "coroaverager3.py", line 111, in <module>
    main(data)
  File "coroaverager3.py", line 83, in main
    group.send(None)  # important! <12>
StopIteration
回溯(最近一次调用):
文件“coroaverager3.py”,第111行,在
主要(数据)
文件“coroaverager3.py”,第83行,在main中
组。发送(无)#重要!
停止迭代

有什么见解吗?

委托生成器分配给
结果[key]
是对的,但它并没有通过这样做来完成。它的执行仍在继续,因为没有地方可以暂停。当然,它会立即从末尾脱落,导致
send(None)
提升
StopIteration
(因为它没有返回值(从
收益率


while True:
是一种添加另一个挂起位置的愚蠢方式;在来自
收益之后的一个额外的收益将更加明显。(如果客户端并不总是知道执行何时完成,那么它可以提供与内部生成器提供的值不同的值。)

很有意义!谢谢。我查了这个:,又把我弄糊涂了。在分配
results[key]
之前,似乎已经处理了
StopIteration
。我认为def gropper(results,key):results[key]=yield from averager()是正确的,当averager完成时,将引发StopIteration。From“”-生成器中的return expr导致在退出生成器时引发StopIteration(expr)。委派生成器仍然是一个生成器,在退出时将引发StopIteration。