- 26
- 0
个人理解:
调用方 .send(None) 后,在 子生成器 break 时抛出 StopIteration 异常,return 返回值后在委托生成器中赋值给 yield from 表达式左侧变量并捕捉 子生成器 抛出的 StopIteration 异常。
问题:
但是为什么此时如果 委托生成器 没有 while True: ,又会抛出 StopIteration 异常?
原代码:
# 子生成器
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():
calc_average = proxy_gen()
next(calc_average) # 预激协程
print(calc_average.send(10)) # 打印:10.0
print(calc_average.send(20)) # 打印:15.0
print(calc_average.send(30)) # 打印:20.0
calc_average.send(None) # 结束协程
# 如果此处再调用calc_average.send(10),由于上一协程已经结束,将重开一协程
if __name__ == '__main__':
main()
委托生成器 中 while True: 的作用是什么呢?
为什么去掉 委托生成器 的 while True: 会抛出 StopIteration 异常呢?
或者说,为什么在 委托生成器 中加上 while True: 就不会抛出 StopIteration 异常了呢?
修改后的代码:
# 子生成器
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():
calc_average = proxy_gen()
next(calc_average) # 预激协程
print(calc_average.send(10)) # 打印:10.0
print(calc_average.send(20)) # 打印:15.0
print(calc_average.send(30)) # 打印:20.0
calc_average.send(None) # 结束协程
# 如果此处再调用calc_average.send(10),由于上一协程已经结束,将重开一协程
if __name__ == '__main__':
main()
异常信息:
10.0
15.0
20.0
计算完毕!!
总共传入 3 个数值, 总和:60,平均数:20.0
Traceback (most recent call last):
File "f:\VSCodeSC\python\tempCodeRunnerFile.python", line 35, in <module>
main()
File "f:\VSCodeSC\python\tempCodeRunnerFile.python", line 31, in main
calc_average.send(None) # 结束协程
StopIteration - 共 0 条
- 全部回答
-
无就将法 普通会员 1楼
在 Python 3 中,
yield from是一个生成器表达式,用于简化代码并允许迭代器类。它由三个部分组成:一个表达式,一个 yield 语句,和一个可迭代对象。在这个表达式中,我们可以包含任何生成器表达式,这将生成一个可迭代对象。yield 语句在表达式内部使用,并在 yield 语句块之后暂停。
如果在 yield 语句块中抛出 StopIteration 异常,那么在 yield 语句块之前,整个表达式就会停止。这就是在 Python 3 中为什么
yield from可以在遇到 StopIteration 异常时停止的原因为何。例如:
```python def counter(start=0): while True: yield start start += 1
print(list(counter())) ```
这段代码会生成一个无限循环,因为
counter函数会在每次 yield 语句块之后都递增start的值。如果在 yield 语句块中抛出 StopIteration 异常,那么循环就会停止。然而,需要注意的是,
yield from是一个生成器表达式,它不会自动处理 StopIteration 异常。在上面的代码中,如果counter函数在 yield 语句块中抛出 StopIteration 异常,那么这个异常将会被counter函数抛出,而不是由生成器表达式处理。
- 扫一扫访问手机版
回答动态

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器更新之后。服务器里面有部分玩家要重新创建角色是怎么回事啊?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题函数计算不同地域的是不能用内网吧?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题ARMS可以创建多个应用嘛?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题在ARMS如何申请加入公测呀?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题前端小程序接入这个arms具体是如何接入监控的,这个init方法在哪里进行添加?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器刚到期,是不是就不能再导出存档了呢?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器的游戏版本不兼容 尝试更新怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器服务器升级以后 就链接不上了,怎么办?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器转移以后服务器进不去了,怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器修改参数后游戏进入不了,是什么情况?预计能赚取 0积分收益
- 回到顶部
- 回到顶部
