浅谈 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 协程通信的基础机制。

🔚 推荐阅读

相关推荐
测试-鹏哥1 天前
要将ITP集成到Jenkins Pipeline中,实现开发发版时自动触发自动化测试
运维·python·测试工具·ci/cd·jenkins
程序员三藏1 天前
Postman接口测试详解
自动化测试·软件测试·python·测试工具·职场和发展·接口测试·postman
L.EscaRC1 天前
Lua语言知识与应用解析
java·python·lua
清空mega1 天前
从零开始搭建 flask 博客实验(5)
后端·python·flask
起予者汝也1 天前
Python基础入门
开发语言·python
snakecy1 天前
cuda10 cudnn7.5--旧版本
python·学习
Owen__z1 天前
GEE统计特定区域特定时间上的Landsat/Sentinel的影像信息
python·sentinel·gee·geemap·landsat
芯联智造1 天前
【stm32协议外设篇】- SU03T 智能语音模块
c语言·开发语言·stm32·单片机·嵌入式硬件
川石课堂软件测试1 天前
Python | 高阶函数基本应用及Decorator装饰器
android·开发语言·数据库·python·功能测试·mysql·单元测试
lqqjuly1 天前
Matlab2025a实现双目相机标定~业余版
开发语言·matlab·相机标定·双目相机