生成器函数中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()函数,咱们逐行追踪执行步骤:
- 调用
d.send(None):生成器启动,执行到yield 100的位置暂停,同时把100作为send(None)的返回值,所以你会看到控制台打印出100。注意:这时候生成器还没走到num = yield那一行! - 调用
d.send(1):生成器从yield 100的位置恢复继续执行,但这个yield是单独存在的(没有赋值给任何变量),所以你传入的1没有被任何变量接收,直接就“丢失”了——这就是你觉得“吞掉num=1”的原因! - 生成器继续执行,走到第一个
num = yield的位置暂停,等待下一次传值。 - 调用
d.send(2):这次2会被赋值给num,执行print("First num: 2"),然后走到下一个num = yield暂停。 - 调用
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
相关产品推荐
相关产品推荐

