在 Python 中,生成器(generator)是一种特殊的迭代器,使用 yield
关键字定义。生成器不仅可以通过next()
获取下一个值,还可以通过send()
方法向生成器发送数据,并在生成器的 yield 语句中接收这些数据。
ok code:
def coroutine_example():
total = 0
while True:
value = yield total
if value is None:
break
total += value
return total
gen = coroutine_example()
next(gen) # 启动生成器
print(gen.send(10)) # 输出 10
print(gen.send(20)) # 输出 30
gen.close() # 关闭生成器
关注一下这里的print(gen.send(10))
怎么就输出10
了?
让我们深入分析,先看一下核心函数def coroutine_example()
怎么执行的 (结合下面的调用代码)👇
next(gen)
首次调用生成器时,该函数会运行到第一个yield total
处暂停。此时 total=0
,yield total
的结果是返回当前total
的值,即0
。
在print(gen.send(10))
中,send(10)
恢复生成器,把10
赋值给value
,然后执行 total += value
→ 更新 total
为 10
,循环绕一圈回到value = yield total
再次遇到yield total
则暂停执行,返回total
的值为10
打印。
这里有一个比较疑惑的点为何 yield total 的结果是 send 的返回值?
因为在生成器中 yield 的双重角色:
- 暂停并返回值:当生成器运行到
yield
时,它会返回一个值 (如这里的 total),并暂停在这里。 - 接受外部数据:当生成器恢复 (通过
send
),yield
表达式的值会被设置为send
的参数(这里是 10)。
那适用场景?-> 需要动态交互、实时数据流或灵活状态切换的场景。