浅谈 Python 中的 yield——yield的返回值与send()的关系

在 Python 中,yield 通常被认为是"生成多个值"的工具,但其实它的作用远不止如此。尤其当我们配合 .send() 方法使用时,yield 不只是"抛出值",还变成了一个表达式 ------ 能够接收来自外部的输入。

这篇文章将深入解释两个关键问题:

  • yield 表达式的值是从哪来的?
  • 使用 send() 和不使用 send() 的区别是什么?

一、基本示例

python 复制代码
def greeter():
    name = yield "你是谁?"
    yield f"你好,{name}"

g = greeter()
print(next(g))         # 输出: 你是谁?
print(g.send("张三"))  # 输出: 你好,张三

重点一:send(x) 会把 x 赋值给上一个 yield 表达式

让我们重点关注这一行代码:

python 复制代码
name = yield "你是谁?"

这是一个"暂停点 + 接收点":

  • yield "你是谁?" 会将 "你是谁?" 发出(返回给调用者),并暂停函数;

  • 当我们调用 g.send("张三") 时,Python 会:

    • 恢复生成器的执行;
    • 把 "张三" 作为 yield 表达式的返回值;
    • 也就是:name = "张三"。

✅ 图示等价理解:

python 复制代码
name = yield "你是谁?"
# 调用 g.send("张三") 后,相当于:
name = "张三"

重点二:如果不用 send(),yield 表达式的值是 None

来看另一个例子:

python 复制代码
def greeter():
    name = yield "你是谁?"
    print(f"你好,{name}")

g = greeter()
print(next(g))    # 第一次执行,返回 "你是谁?"
print(next(g))    # 第二次执行,没有 send,name 是多少?

✅ 输出:

复制代码
你是谁?
你好,None

因为第二次使用的是 next(g),而不是 send(x),所以:

yield 表达式的返回值默认是 None。


二、完整对比总结表

操作方式 功能说明 yield 表达式的值
next(generator) 恢复执行但不提供返回值 None
generator.send(x) 恢复执行并将 x 作为返回值 x(赋值给 yield 表达式)

三、思维模型类比:问答式通信

python 复制代码
question = yield "你是谁?"
  • yield 提出一个问题;
  • 外部使用 send("张三") 作为回答;
  • 于是 question = "张三"。

这就像是协程之间的双向通信,是构建调度器、LLM代理、LangGraph等系统的核心通信模式。


四、以三段式协程对话为例

python 复制代码
def dialogue():
    name = yield "你是谁?"
    age = yield f"你好,{name},你几岁?"
    yield f"{name},你今年 {age} 岁了!"

g = dialogue()
print(next(g))           # → "你是谁?"
print(g.send("张三"))    # → "你好,张三,你几岁?"
print(g.send(18))        # → "张三,你今年 18 岁了!"

输出:

复制代码
你是谁?
你好,张三,你几岁?
张三,你今年 18 岁了!

五、总结

  • yield 可以是表达式;
  • send(x) 把 x 作为上一个 yield 表达式的返回值;
  • 如果不用 send() 而用 next(),返回值默认是 None;
  • yield + send() 构成了 Python 协程通信的基础机制。

🔚 推荐阅读

相关推荐
大貔貅喝啤酒7 分钟前
Unittest框架使用教程
自动化测试·python
一个简单的TTS开发者24 分钟前
中文TTS工具有哪些-8款主流方案横向对比
人工智能·后端·python·indextts
yunfanleo27 分钟前
temperature 详解:大模型采样参数原理、三种用法与工程实践
人工智能·python·rpa
卢锡荣28 分钟前
乐得瑞Type-c接口产品描述
c语言·开发语言
晴天的雨.99229 分钟前
【C++】模板进阶
开发语言·c++·算法
CarIise42 分钟前
Maven依赖传递与聚合工程
python·r语言·django
VidDown9 小时前
24fps 转 25fps 不只是改个数字:帧率转换、PAL/NTSC 与音频补偿
python·网络协议·音视频·视频编解码·视频
死磕音视频11 小时前
让小模型做选择题:限定候选项并读取 logits 概率的入门实践(附 Python 代码)
开发语言·python·大模型·文本分类·transformers
凤山老林11 小时前
Spring Boot 接入国密 SM2/SM3/SM4 的一些实践记录
spring boot·后端·python
pride.li13 小时前
第03章 Python 教程-基础语法:注释与变量
服务器·前端·后端·python·算法·计算机视觉