真实面经题目 · 原创解析
Python 的生成器是如何实现的?
Python 生成器的本质是带有可暂停执行状态的迭代器。回答要讲清 yield 如何保存栈帧、next/send 如何恢复执行,以及它和普通函数、迭代器的关系。
真实面经题目 · 原创解析
Python 生成器的本质是带有可暂停执行状态的迭代器。回答要讲清 yield 如何保存栈帧、next/send 如何恢复执行,以及它和普通函数、迭代器的关系。
包含 yield 的函数被调用时不会立即执行函数体,而是返回一个 generator 对象。这个对象实现了迭代器协议,有 __iter__ 和 __next__。每次 next 或 send 调用时,解释器从上次暂停的 yield 位置继续执行,直到遇到下一个 yield 返回值,或者函数结束抛出 StopIteration。生成器内部会保存执行帧,包括局部变量、指令位置和异常状态,所以能做到惰性求值和暂停恢复。
普通函数调用会执行到 return 后返回结果。生成器函数调用只创建 generator 对象,不立即跑函数体,真正执行发生在 next、send 或 for 循环拉取值时。
生成器对象天然实现 __iter__ 和 __next__,所以可以被 for、list、sum 等消费。for 循环内部反复调用 next,捕获 StopIteration 后结束。
执行到 yield 时,生成器把值返回给调用方,同时保留当前执行帧。下一次恢复时从 yield 后面的指令继续跑,局部变量不会丢失。
send 可以把值送回暂停的 yield 表达式,throw 可以在暂停处注入异常,close 可以结束生成器。它们让生成器不只是取数,还能做协程式协作。
生成器适合流式读取、大文件处理、惰性计算、无限序列和管道组合。它不一次性把所有结果放进内存,但要注意只能按执行状态向前消费。
生成器是一种迭代器,它自动实现迭代器协议;迭代器是更广义的接口,也可以用类手动实现。
yield 返回一个中间值并暂停,后续还能恢复;return 结束函数,生成器中 return 的值会放在 StopIteration 的 value 中。
它一次只生成当前需要的元素,不需要提前构造完整列表,尤其适合文件流、网络流和长序列。