浅谈 Python 中的 yield——生成器对象与函数调用的区别

我们来看这么一个例子:

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

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

执行流程:

复制代码
next(g):执行到 yield,返回 "你是谁?";

send("张三"):将 "张三" 送入上次 yield 表达式的返回值,继续执行。

send() 是构建协程通信、任务调度器的核心机制之一(如 asyncio、trio、LangGraph 内核)。

g = greeter()是将 greeter() 执行的结果赋值给 g ,这个结果是一个生成器对象(generator) ,而不是把函数本身赋值给 g。


🔍 详细分析

当我们写:

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

此时,greeter 是一个函数对象(还没执行)。

当我们调用 greeter():

python 复制代码
g = greeter()

Python 会:

  • 执行函数定义,但并不运行函数体;
  • 因为函数中含有 yield,所以它会返回一个 生成器对象 ,即 g 是一个 generator。

我们可以验证:

python 复制代码
print(type(g))  # <class 'generator'>

这就意味着:

python 复制代码
g = greeter()  # g 现在是生成器对象,不是函数本身

✅ 所以两种情况的对比:

写法 含义 类型
g = greeter 把函数本身赋值给变量 g,不执行 <function>
g = greeter() 执行函数,返回一个生成器对象 <generator>

✅ 举个例子验证一下

python 复制代码
def example():
    yield 42

print(example)      # <function example at 0x...>
print(example())    # <generator object example at 0x...>

✅ 总结

greeter() 是函数调用表达式,执行时返回一个生成器对象 ;所以 g = greeter() 是在 将生成器对象赋值给 g ,而不是将函数本身赋值给 g。

相关推荐
量化炼金 (CodeAlchemy)4 分钟前
【量化研究】美股历史数据获取:Yahoo Finance 转 Zorro 回测格式
python·量化研究·量化交易
曹牧6 分钟前
C#:The operation has timed out
开发语言·c#
你看我名字16 分钟前
数眼智能 Search + Reader 实战:联网问答怎样避免“搜到了,却引用错了”
android·java·开发语言
小嘉丶学长18 分钟前
Day13 · 列表与元组
linux·运维·服务器·开发语言·python
努力努力再努力wz22 分钟前
【Lua入门系列】从 C++ 迭代器到 Lua 迭代器:一文深入理解 Lua 有状态以及无状态迭代器与泛型for、闭包、ipairs、pairs 和 next
开发语言·c++·lua
小小张说故事28 分钟前
Python 的 int 为什么不会溢出?拆开 PyLongObject 和它背后那串变长数组
python
努力实干30 分钟前
第二阶段 · 第 7 课:C++ 多线程与线程安全
开发语言·c++·安全
爱聊灵光的维C1 小时前
C语言初阶:关于函数设计的详细讲解和注意事项
c语言·开发语言·青少年编程·蓝桥杯·学习方法
熊猫钓鱼>_>1 小时前
上架审核常见驳回与隐私合规清单:过审前先自查这 8 条【鸿蒙心迹】
开发语言·前端·华为·华为云·harmonyos·openharmony·ai制作
威哥爱编程1 小时前
Python 智能体开发实战 03:聊十轮就“失忆”,账单还翻倍?管好上下文,Token 立省一半
python·agent