迭代器天然支持延迟加载,因其按需通过__next__()返回元素,内存中仅保留当前项和控制变量;文件对象、map/filter结果等内置类型默认具备该特性,自定义迭代器或生成器可进一步控制数据获取逻辑。

迭代器本身不直接“实现”延迟加载,但它天然支持延迟加载的数据流处理——关键在于它按需返回元素,而不是一次性把全部数据装进内存。
迭代器为什么适合延迟加载
迭代器对象只在调用 next() 时才计算并返回下一个值,内部状态(比如索引、游标、文件指针)由 __next__() 方法维护。这意味着:
- 数据可以来自实时生成(如传感器读数)、大文件逐行读取、数据库游标分页查询,甚至无限序列
- 内存中始终只保留当前项和少量控制变量,不保存整个数据集
- 遍历未开始前,实际数据加载尚未触发;中断遍历时,后续数据也不会被加载
用内置类型快速启用延迟加载
很多常见对象本身就是可迭代的,只需用 iter() 转成迭代器即可获得延迟行为:
-
文件对象:open() 返回的对象默认就是迭代器,
for line in f:是逐行读取,不加载整文件 -
字典/列表等容器:虽不是迭代器,但
iter(d)或iter(lst)可获得其迭代器,配合 next() 实现手动步进 -
map/filter 等函数结果:Python 3 中它们返回迭代器,
map(str, [1,2,3])不立刻执行转换,只在迭代时逐个调用
自定义迭代器控制加载逻辑
当需要更精细控制(比如分页查数据库、带重试的网络流、条件跳过),可写类实现迭代协议:
- 在 __next__() 中封装一次数据获取动作(如 fetch_one_row()、read_next_chunk())
- 状态变量(如 offset、page_no、buffer)存在实例属性里,随每次 next() 更新
- 数据耗尽时主动 raise StopIteration,这是协议要求,也是 for 循环终止依据
例如模拟分页 API 调用:
每次 next() 触发一次 HTTP 请求,解析响应并返回一条记录,不缓存历史响应。
生成器是更简洁的替代写法
如果逻辑以“产生一系列值”为主,用 yield 写生成器函数比手写类更自然:
- 函数体内每遇到一个 yield 就暂停,返回值,并记住当前执行位置
- 下次调用 next() 时从中断处继续,可嵌套循环、条件判断、异常处理
- 本质仍是迭代器,但省去 __iter__/__next__ 的样板代码
典型场景:逐行处理超大日志文件、实时生成斐波那契数列、从 Kafka 消费消息流。

















