真实面经题目 · 原创解析

Python 的生成器是如何实现的?

Python 生成器的本质是带有可暂停执行状态的迭代器。回答要讲清 yield 如何保存栈帧、next/send 如何恢复执行,以及它和普通函数、迭代器的关系。

出现于:腾讯 · 算法

60 秒回答模板

包含 yield 的函数被调用时不会立即执行函数体,而是返回一个 generator 对象。这个对象实现了迭代器协议,有 __iter__ 和 __next__。每次 next 或 send 调用时,解释器从上次暂停的 yield 位置继续执行,直到遇到下一个 yield 返回值,或者函数结束抛出 StopIteration。生成器内部会保存执行帧,包括局部变量、指令位置和异常状态,所以能做到惰性求值和暂停恢复。

考点 返回生成器对象
难度 真实面经题
回答目标 讲清方法、取舍和追问

深入解析

01

函数调用不同

普通函数调用会执行到 return 后返回结果。生成器函数调用只创建 generator 对象,不立即跑函数体,真正执行发生在 next、send 或 for 循环拉取值时。

02

遵循迭代协议

生成器对象天然实现 __iter__ 和 __next__,所以可以被 for、list、sum 等消费。for 循环内部反复调用 next,捕获 StopIteration 后结束。

03

yield 暂停恢复

执行到 yield 时,生成器把值返回给调用方,同时保留当前执行帧。下一次恢复时从 yield 后面的指令继续跑,局部变量不会丢失。

04

send 和异常协作

send 可以把值送回暂停的 yield 表达式,throw 可以在暂停处注入异常,close 可以结束生成器。它们让生成器不只是取数,还能做协程式协作。

05

适用场景

生成器适合流式读取、大文件处理、惰性计算、无限序列和管道组合。它不一次性把所有结果放进内存,但要注意只能按执行状态向前消费。

易错点

  • 不要说生成器函数调用会立刻执行函数体,实际只返回 generator 对象。
  • 不要把 yield 当成普通 return,yield 会暂停并保留状态。
  • 不要忽略 StopIteration,迭代结束依赖这个机制。
  • 不要默认生成器能随机访问,它通常只能按执行顺序消费。

面试官追问

生成器和迭代器是什么关系?

生成器是一种迭代器,它自动实现迭代器协议;迭代器是更广义的接口,也可以用类手动实现。

yield 和 return 有什么区别?

yield 返回一个中间值并暂停,后续还能恢复;return 结束函数,生成器中 return 的值会放在 StopIteration 的 value 中。

生成器为什么省内存?

它一次只生成当前需要的元素,不需要提前构造完整列表,尤其适合文件流、网络流和长序列。