
处理大数据内存爆炸?想要实现无限序列?Python 生成器(Generator)是你的必备武器。本文不仅讲解语法,更深入底层机制,带你从“会用”到“精通”。
在日常开发中,你是否遇到过这样的场景:
- • 试图读取一个 10GB 的日志文件,结果程序直接 MemoryError 崩溃。
- • 需要生成一个 斐波那契数列,却不知道何时停止,导致列表无限膨胀。
- • 写了一堆数据处理函数,代码耦合严重,难以维护。
如果中枪了,那么今天的主角 Python 生成器(Generator) 就是为你量身定做的解决方案。
很多人知道 yield 关键字,但真的理解它的状态保持机制和双向通信能力吗?今天,我们就来一次深度剖析。
01 为什么需要生成器?
在理解生成器之前,我们先看看传统的列表(List)有什么问题。
假设我们要处理一个包含 100 万个数字的序列,每个数字平方后返回。
普通列表做法:

生成器做法:

核心区别:
- • 列表:是积极的,一次性把所有结果算好存起来。
- • 生成器:是惰性的(Lazy Evaluation),你问我要一个,我算一个给你。
02 创建生成器的两种方式
1. 生成器函数(Generator Function)
这是最常见的方式。只要函数中包含 yield 关键字,它就不再是普通函数,而是一个生成器工厂。

关键点: 每次调用 next(),函数从上次 yield 挂起的地方继续执行,直到遇到下一个 yield。
2. 生成器表达式(Generator Expression)
类似于列表推导式,但使用圆括号 ()。

建议: 如果数据量巨大,且只需要遍历一次,优先使用生成器表达式。
03 深入底层:yield 到底做了什么?
这是加深理解的关键。yield 不仅仅是“返回值”,它是一个时间机器。
- 1. 冻结状态:当执行到 yield 时,函数的局部变量、指令指针(执行到哪一行)都被冻结保存。
- 2. 交出控制权:将 yield 后面的值返回给调用者,函数暂停。
- 3. 恢复现场:当下一次 next() 调用时,函数从冻结的地方“解冻”,局部变量的值保持不变,继续向下执行。
图解记忆:
想象你在看电影(函数执行)。
- • return 是看完电影,离场,下次再来得重新买票从头看。
- • yield 是按下暂停键。你可以出去喝杯水(返回数据),回来按播放键(next),剧情接着刚才的地方继续,主角的记忆(局部变量)还在。
04 进阶玩法:双向通信 (send, throw, close)
很多人学到 yield 就停了,其实生成器支持协程(Coroutine) 特性,可以实现双向通信。
1. send() 方法
next(gen) 等价于 gen.send(None)。但 send(value) 可以把值发送进生成器内部,成为 yield 表达式的返回值。

应用场景: 这种特性常用于构建数据管道或状态机。
2. throw() 和 close()
- • gen.throw(Exception): 在生成器内部抛出异常,可用于错误处理。
- • gen.close(): 强制关闭生成器,触发 GeneratorExit 异常,常用于清理资源(如关闭文件)。
05 实战场景:哪里该用生成器?
场景 1:读取超大文件
不要一次性 read() 或 readlines()。

场景 2:数据流处理管道
将多个生成器串联,形成处理流水线。

这种写法既节省内存,又让逻辑清晰解耦。
场景 3:无限序列
生成器不需要知道序列长度。

06 避坑指南
虽然生成器很强大,但也有几个坑需要注意:
- 1. 只能遍历一次:生成器是“消耗品”。一旦遍历结束(抛出 StopIteration),就不能再次使用了。如果需要重用,请重新创建生成器或转为列表(如果内存允许)。
- 2. 无法获取长度:生成器没有 __len__ 方法,你不能调用 len(gen)。因为它是惰性的,它自己都不知道后面还有多少个。
- 3. 小心 yield 在循环中的变量捕获:如果在循环中创建生成器并引用了循环变量,注意闭包陷阱(虽然这在生成器中不如在普通函数中常见,但仍需留意作用域)。
07 总结
生成器是 Python 中最优雅的特性之一。
- • 核心关键字:yield
- • 核心优势:节省内存、支持无限序列、代码解耦。
- • 核心机制:状态保持、惰性求值。
- • 进阶能力:send() 实现协程通信。
学习建议:
不要死记硬背。试着把你项目中那个“读取大文件”或者“处理大列表”的函数,改写成生成器版本,感受一下内存的变化。
扫码二维码 获取免费视频学习资料

- 本文固定链接: http://www.phpxs.com/post/14047/
- 转载请注明:转载必须在正文中标注并保留原文链接
- 扫码: 扫上方二维码获取免费视频资料