send()方法支持运行时注入外部业务变量,next()仅推进生成器且等价于send(None);yield兼具产出值和接收值的双重功能,通过x = yield value实现变量注入与条件处理。

用 next() 本身无法动态注入变量——它只负责推进生成器到下一个 yield,不传值。真正支持“运行时注入外部业务变量”的是 send() 方法,next() 只是它的特例(等价于 send(None))。
理解 yield 的双重身份:出口 + 入口
yield 不仅能“产出”一个值,还能“接收”一个值。当生成器执行到 x = yield value 时:
- 先向外返回
value(作为本次next()或send()的返回值); - 然后暂停,等待下一次调用;
- 下一次若用
send(v),则v就赋给x;若用next(),则x被设为None。
注入业务变量的典型流程
以实时处理用户订单为例,你需要根据外部传入的订单类型(如 "vip"、"trial")动态调整生成策略:
- 首次必须用
next(gen)或gen.send(None)启动生成器(越过第一个yield前的初始化逻辑); - 后续每次调用
gen.send(order_type),就能把当前业务变量传进生成器内部; - 生成器在
yield处接收到该变量后,可做条件判断、状态切换或参数计算。
一个实用示例:带业务规则的流水号生成器
(支持按客户等级动态生成不同前缀的编号)
def serial_generator():
prefix = "STD"
while True:
# 等待外部传入业务变量,比如客户等级
level = yield f"{prefix}-001"
if level == "vip":
prefix = "VIP"
elif level == "trial":
prefix = "TRI"
elif level == "admin":
prefix = "ADM"
<p>gen = serial_generator()
next(gen) # 启动:输出 'STD-001'</p><p>print(gen.send("vip")) # 输出 'VIP-001'
print(gen.send("trial")) # 输出 'TRI-001'
print(gen.send("admin")) # 输出 'ADM-001'
</p>
注意事项与避坑点
- 第一次调用不能直接
send(x)(会报TypeError: can't send non-None value to a just-started generator),务必先next()或send(None); - 生成器中所有
yield都应出现在赋值语句右侧(如x = yield val),否则传入的值会被丢弃; - 如果某次不需要注入新变量,仍可用
next(gen),此时对应位置接收到的是None,需在逻辑中做好判空; - 生成器关闭后(
close()或自然结束)再调用send()会触发StopIteration或GeneratorExit异常。










