yield生成器的原理+保存在哪儿了?
关于 yield 的原理
你的回答:“惰性计算与懒加载... 外部调用 next 时... 保存快照... 始终只占用内存中的固定内存。”
✅ 哪里对了:
惰性求值 (Lazy Evaluation):术语使用准确。
固定内存 (Constant Memory / O(1)):这是最核心的价值,你答到了。
控制权交接:你理解了 next() 触发执行,这是对的。
❌ 哪里不严谨 (需要修正):
“保存快照”:这个词稍微有点偏。更专业的说法是 “挂起 (Suspend)” 和 “恢复 (Resume)”。
“只占用一行对象的计数”:不仅仅是一行。生成器对象本身维护了一个 栈帧 (Stack Frame)。
底层机制:你提到了“保存快照”,但没说清楚保存在哪。
📚 深度补课:yield 到底把状态存在哪了?(面试加分项)
面试官可能会追问:“你说保存了快照,那这个快照存在哪?为什么普通函数调用完就销毁了,生成器却能记住?”
标准答案(请记忆):
普通函数 (Subroutine):
调用时:在 C 栈 (C Stack) 上创建一个栈帧。
结束时:栈帧直接销毁,所有局部变量消失。
特点:用完即弃。
生成器 (Generator / Coroutine):
编译时:Python 编译器发现代码里有 yield,就会把它标记为一个生成器函数。
调用时:不会立即执行,而是返回一个 生成器对象 (Generator Object)。
堆内存存储:生成器的 栈帧 (Frame) 是分配在 堆内存 (Heap) 上的,而不是栈上!
挂起时:yield 只是把 指令指针 (Instruction Pointer) 指向了下一行代码,并把这个在堆上的栈帧“封存”起来。
恢复时:next() 找到堆上的这个栈帧,恢复变量状态,继续往下跑。
一句话总结:
“普通函数活在栈里,活不长;生成器活在堆里,能‘冻龄’。”

浙公网安备 33010602011771号