You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python协程中yield执行异常:输出与预期不符的原因排查

生成器执行流程分析与问题修正

你的代码:

def gen():
    while True:        # line 2
        d = yield      # line 3
        yield d        # line 4

x = gen()
next(x)

for i in (3, 4, 5):
    print(x.send(i))   # line 10

实际输出:

3
None
5

你的理解有遗漏,核心问题是每次send()调用会推进生成器执行到下一个yield语句,并返回该yield产出的值,而你的生成器包含两个yield节点,导致循环中send()的返回值交替对应有效传入值和空产出。

详细执行流程拆解

  1. x = gen():创建生成器对象,未启动。
  2. next(x):启动生成器,执行到line3的d = yield(该yield无产出值,默认产出None),生成器在此暂停,等待接收外部传入值。
  3. 第一次循环i=3,调用x.send(3):
    • 生成器从line3的暂停处恢复,将3赋值给d。
    • 继续执行到line4的yield d,产出3,send()方法返回该值,打印3。
    • 生成器暂停在line4的yield d处。
  4. 第二次循环i=4,调用x.send(4):
    • 生成器从line4的暂停处恢复,执行完line4后回到line2的循环,走到line3的d = yield。
    • 该yield无产出值(产出None),send()方法返回这个None,打印None。
    • 同时将4赋值给d,生成器暂停在line3的yield处。
  5. 第三次循环i=5,调用x.send(5):
    • 生成器从line3的暂停处恢复,将5赋值给d。
    • 继续执行到line4的yield d,产出5,send()方法返回该值,打印5。
    • 生成器暂停在line4的yield d处。

修正方案

如果要得到预期的3、4、5输出,需要让生成器每次send()对应一次有效产出,调整生成器逻辑即可:

写法一

def gen():
    d = None
    while True:
        d = yield d  # 接收外部值并产出,每次暂停在此处

x = gen()
next(x)  # 预激生成器,首次产出None可忽略

for i in (3, 4, 5):
    print(x.send(i))

写法二(更简洁)

def gen():
    while True:
        yield (yield)  # 先接收外部值,再产出该值

x = gen()
next(x)

for i in (3, 4, 5):
    print(x.send(i))

两种写法都能让每次send(i)返回i,得到你预期的输出结果。

内容的提问来源于stack exchange,提问作者mlz7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 19:45:50