在 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)。
那适用场景?-> 需要动态交互、实时数据流或灵活状态切换的场景。