浅谈 Python 中的 yield——生成器对象与函数调用的区别
我们来看这么一个例子:
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
。
🔍 详细分析
当我们写:
def greeter():name = yield "你是谁?"yield f"你好,{name}"
此时,greeter
是一个函数对象(还没执行)。
当我们调用 greeter()
:
g = greeter()
Python 会:
- 执行函数定义,但并不运行函数体;
- 因为函数中含有
yield
,所以它会返回一个 生成器对象,即g
是一个generator
。
我们可以验证:
print(type(g)) # <class 'generator'>
这就意味着:
g = greeter() # g 现在是生成器对象,不是函数本身
✅ 所以两种情况的对比:
写法 | 含义 | 类型 |
---|---|---|
g = greeter | 把函数本身赋值给变量 g ,不执行 | <function> |
g = greeter() | 执行函数,返回一个生成器对象 | <generator> |
✅ 举个例子验证一下
def example():yield 42print(example) # <function example at 0x...>
print(example()) # <generator object example at 0x...>
✅ 总结
greeter()
是函数调用表达式,执行时返回一个生成器对象;所以g = greeter()
是在 将生成器对象赋值给g
,而不是将函数本身赋值给g
。