yield是表达式而非语句,实现协程的可控上下文切换;它保存状态并支持send传值,return终止迭代并携带返回值,yield from委托子生成器并透传控制流与异常。

yield 不是暂停,是状态快照和协程切换点
调用含 yield 的函数时,它不会立即执行函数体,而是返回一个 generator 对象。真正开始执行要等到第一次调用 __next__()(或 next())。每次遇到 yield 表达式,函数会保存当前栈帧、局部变量、指令指针,并把右侧值返回给调用方;之后挂起,等待下一次 next() 或 send() 触发恢复。
常见误解是“yield 暂停函数”,其实它更接近一次「可控的上下文切换」——Python 解释器在背后维护了生成器的状态机(GEN_CREATED → GEN_RUNNING → GEN_SUSPENDED → GEN_CLOSED)。
yield 表达式本身有返回值,且可接收外部传入值
yield 是表达式,不是语句。这意味着它可以被赋值,也可以有返回值。当用 g.send(value) 恢复生成器时,value 会成为当前 yield 表达式的计算结果。
- 首次调用
next(g)时,yield左侧接收的是None - 后续用
g.send(x),则当前yield表达式求值为x,比如data = yield item中data就等于传入的x - 若用
next(g)而非send(),等价于send(None),但不能向刚启动(尚未走到第一个yield)的生成器send非None值,否则抛TypeError: can't send non-None value to a just-started generator
return 在生成器中抛 StopIteration,且可带返回值
生成器函数中出现 return(哪怕没带值),会立即终止迭代,并引发 StopIteration 异常。从 Python 3.3 开始,return expr 中的 expr 会作为 StopIteration.value 属性被暴露出来。
立即学习“Python免费学习笔记(深入)”;
示例:
客客出品专业威客系统英文名称KPPW,也是keke produced professional witkey的缩写。KPPW是一款基于PHP+MYSQL技术构架的威客系统,积客客团队多年实践和对威客模式商业化运作的大量调查分析而精心策划研发,是您轻松搭建威客网站的首选利器。KPPW针对威客任务和商品交易模式进行了细致的分析,提供完善威客任务流程控制解决方案,并将逐步分享威客系统专业化应用作为我们的
def gen():
yield 1
return "done"
g = gen()
print(next(g)) # 输出 1
try:
next(g)
except StopIteration as e:
print(e.value) # 输出 "done"
注意:不能在生成器里用 return 后再写普通语句,那部分代码永远不会执行;也不能在 yield 后面直接跟 return(语法允许,但逻辑上无意义)。
yield from 是语法糖,但底层是委托迭代与异常传递
yield from subgen 不只是“展开子生成器”,它建立了调用方 ↔ 子生成器之间的双向通道:不仅自动迭代 subgen,还把 send()、throw()、close() 都透传过去,并在子生成器结束时自动把它的返回值(StopIteration.value)变成外层 yield from 表达式的值。
容易踩的坑:
- 如果
subgen不是生成器或迭代器(比如是 list),yield from会隐式调用iter(),但不会报错;但若subgen是普通函数且没yield,就会报TypeError: 'xxx' object is not iterable -
yield from内部捕获并重新抛出子生成器的GeneratorExit,所以不要在子生成器里用try/except GeneratorExit去吞掉它,否则close()失效 - 想让
yield from返回值参与外层逻辑?必须用赋值,如result = yield from subgen()
真正难调试的地方往往不在 yield 本身,而在多个生成器嵌套 + 异常传播 + 手动 send 交互时的状态错位——这时候别靠脑补,用 sys.settrace 或 inspect.getgeneratorstate() 看实际状态更靠谱。









