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