send() 是生成器的一个特殊方法,它不仅能恢复生成器的执行,还能向生成器发送一个值,这个值会成为当前 yield 表达式的返回值。
一、send() 的核心作用
| 方法 | 作用 | 能否传值 |
|---|---|---|
next(g) | 恢复执行到下一个 yield | 不能 |
g.send(value) | 恢复执行,并传入一个值 | 能 |
说明:send(value) 传入的值会赋值给当前 yield 表达式。
def demo():
x = yield 1 # yield 1 返回给外部,同时接收外部 send 的值
print(f"收到: {x}")
y = yield 2
print(f"收到: {y}")
yield 3
g = demo()
print(next(g)) # 1(执行到第一个 yield,暂停)
print(g.send(100)) # 100 赋给 x → 打印"收到: 100" → 执行到 yield 2 → 返回 2
print(g.send(200)) # 200 赋给 y → 打印"收到: 200" → 执行到 yield 3 → 返回 3
二、执行过程
代码示例
def accumulator():
total = 0
while True:
value = yield total # ① 返回当前 total,等待接收值
if value is None:
break
total += value
gen = accumulator()
逐步执行
| 步骤 | 代码 | 执行过程 | 返回值 |
|---|---|---|---|
| 1 | next(gen) | 执行到 yield total,total=0,暂停 | 0 |
| 2 | gen.send(10) | ① 10 赋给 value② total += 10 → total=10③ 回到循环,执行到 yield total,暂停 | 10 |
| 3 | gen.send(20) | ① 20 赋给 value② total += 20 → total=30③ 回到循环,执行到 yield total,暂停 | 30 |
| 4 | gen.send(None) | value=None → break → 生成器结束 | StopIteration |
三、send() 和 next() 的等价关系
next(g) # 等价于 g.send(None)
实际上,next(g) 内部调用的就是 g.send(None)。
def gen():
yield 1
yield 2
g = gen()
print(next(g)) # 1
print(g.send(None)) # 2(等价于 next(g))
四、第一次调用不能用 send()
规则:生成器第一次恢复执行时,必须用 next(g) 或 g.send(None),不能 send 非 None 的值。
def gen():
x = yield 1
print(x)
g = gen()
# g.send(100) # TypeError: can't send non-None value to a just-started generator
next(g) # 必须先启动
g.send(100) # 之后可以 send
原因:生成器在第一次执行前没有 yield 表达式来接收值。
五、send() 的执行流程图

send(value) 把 value 传给当前暂停的 yield 表达式,yield 表达式的返回值就是 send 传入的值。第一次调用必须用 next(g) 或 send(None) 来启动生成器。

490

被折叠的 条评论
为什么被折叠?



