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

生成器函数中yield返回整数时为何会吞掉send()传入的对象?

生成器函数中yield返回整数时为何会吞掉send()传入的对象?

嘿,这个问题其实是没搞懂生成器的执行顺序和send()方法的工作逻辑,咱们一步步拆解来看就清楚啦~

先回顾下你的eee()函数的执行流程,这是正常接收值的情况:

  • 调用e.send(None):生成器启动,走到第一个num = yield的位置暂停,这里yield后面没有值,所以send(None)没有返回内容,只是完成启动。
  • 调用e.send(1):把1传递给生成器,这个值会被赋值给num,然后执行print("First num: 1"),接着走到下一个num = yield暂停。
  • 后续的send(2)、send(3)逻辑一样,每个传入的值都被对应的num接收并打印,直到最后send(3)执行完第三个print,生成器结束触发StopIteration。

接下来重点看出问题的ddd()函数,咱们逐行追踪执行步骤:

  1. 调用d.send(None):生成器启动,执行到yield 100的位置暂停,同时把100作为send(None)的返回值,所以你会看到控制台打印出100。注意:这时候生成器还没走到num = yield那一行!
  2. 调用d.send(1):生成器从yield 100的位置恢复继续执行,但这个yield是单独存在的(没有赋值给任何变量),所以你传入的1没有被任何变量接收,直接就“丢失”了——这就是你觉得“吞掉num=1”的原因!
  3. 生成器继续执行,走到第一个num = yield的位置暂停,等待下一次传值。
  4. 调用d.send(2):这次2会被赋值给num,执行print("First num: 2"),然后走到下一个num = yield暂停。
  5. 调用d.send(3):3被赋值给num,执行print("Second num: 3"),接着走到最后一个num = yield暂停,此时生成器还没结束,所以没有触发StopIteration。

如果想让ddd()能接收到send(1)的值,只需要把第一个yield改成赋值语句就行,比如:

def ddd_fixed():
    num = yield 100  # 把yield的返回和赋值结合起来
    print(f"First num: {num}")
    num = yield
    print(f"Second num: {num}")
    num = yield
    print(f"Third  num: {num}")

d_fixed = ddd_fixed()
print(d_fixed.send(None))  # 输出100
d_fixed.send(1)            # 打印First num: 1
d_fixed.send(2)            # 打印Second num: 2
try:
    d_fixed.send(3)        # 打印Third num: 3,触发StopIteration
except StopIteration:
    print("Done with fixed d")

总结一下核心逻辑:

  • 生成器启动时的send(None)是让它走到第一个yield的位置,返回yield后面跟着的值(如果有的话)。
  • 当生成器在yield X的位置暂停时,下一次send(Y)会让生成器继续执行,但Y只会被赋值给变量,当且仅当这个yield是在赋值语句的右边(比如num = yield X或者num = yield)。

备注:内容来源于stack exchange,提问作者jouell

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 10:57:58