Python 生成器中的 yield 和 send() 使用

The value of a yield expression is None, until the program calls the method send(value).
yield表达式返回 None,直到使用 send(value) 方法

先看看生成器和函数在运行时的浅显差异

def my_gen(i):
    while True:
        value = (yield i + 1)
        i += 1
        if value is None:
            print("调用next()时 yield 返回值为 None")
        else:
            print(f"调用send(value) yield 返回值为 {value}")

            
def my_list(i):
    return list(range(i))

# 为下面两条语句设置断点,并进行调试,选择步入
a = my_gen(1) 
b = my_list(1) # 你会发现只有my_list()函数在一开始被调用

在以下调用 next() 和 send() 的所有位置设置断点,选择步入

# 注意在同一行使用多个next时可能会发生一开始没有想到的结果
# print(next(a),next(a))
print("第一次 next() 运行结果:")
print(f"{next(a)}\n") # 1

print("第二次 next() 运行结果:")
print(f"{next(a)}\n") # 2

value = 10
return_value = a.send(value) # 3
print(return_value) # 返回的值为 i+1 (i==3)

第一次 next() 运行结果:
2
第二次 next() 运行结果:
调用next()时 yield 返回值为 None
3
调用send(value) yield 返回值为 10
4

下面的序号解释对应代码块中注释的语句:

  1. 可以发现并没有触发函数的if语句,在执行 yield 语句后 函数 便返回值了,注意,此时 yield 表达式并没有返回值给 value,在下一次运行时才会返回
  2. 此时会续上之前 yield ,像是被挂起的进程又被 next() 唤醒,并给 value 赋值,从 i += 1 往下运行,经过循环回到开头,然后遇到 yield 再次被挂起
  3. 注意,此时并没有从头开始,而是像唤醒进程一样继续,但是,你会发现生成器内部 yield 返回给 value 的值变成了10,这个值刚好是 send() 从外部发送的值,但你在一开始其实并没有执行 yield,若你有些困惑,不妨看看注释1

相关链接&图片:

Python Generators
PEP342
Python基础教程

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hoper.J

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值