可迭代对象有__iter__方法,返回迭代器;迭代器对象同时有__iter__和__next__方法,负责逐个产出数据。for循环底层即调用iter()获取迭代器,再反复调用next()直至StopIteration。

迭代器的本质:可迭代对象与迭代器对象的区别
很多人混淆“可迭代对象”和“迭代器对象”。简单说:可迭代对象(如 list、str、dict、range)有 __iter__ 方法,能返回一个迭代器;而迭代器对象本身有 __iter__ 和 __next__ 两个方法,真正负责逐个产出数据。调用 iter(obj) 得到迭代器,再反复调用 next(it) 取值,直到抛出 StopIteration 异常——这就是 for 循环底层的执行逻辑。
手写一个迭代器:掌握 __iter__ 与 __next__ 的协作机制
自定义迭代器必须同时实现这两个方法:
- __iter__ 必须返回 self(通常是迭代器自身),保证它能被 for 或 iter() 正确识别;
- __next__ 负责返回下一个值,没数据时 raise StopIteration,不能返回 None 或静默退出。
例如实现一个倒序遍历数字的迭代器:
class Countdown:
def __init__(self, start):
self.current = start
def __iter__(self):
return self
def __next__(self):
if self.current
raise StopIteration
self.current -= 1
return self.current + 1
生成器函数:更简洁的迭代器写法
用 def 定义、含 yield 的函数,调用后直接返回生成器对象(即迭代器)。它自动实现了 __iter__ 和 __next__,状态挂起/恢复由解释器管理,比手动写类更轻量、更常用。
关键点:
- yield 表达式暂停函数,保存局部变量和执行位置;
- 每次 next() 触发,从上次 yield 处继续执行,直到下一个 yield 或函数结束;
- return(非 None)在生成器中会作为 StopIteration 的 value 抛出。
实战场景:文件逐行处理、无限序列、管道式数据流
迭代器的价值在资源受限或数据流式场景中尤为突出:
- 大文件读取不加载全量:open() 返回的文件对象本身就是迭代器,for line in f: 比 f.readlines() 节省内存;
- 生成斐波那契、素数等无限序列:用生成器 yield 一个接一个产出,按需计算;
- 链式处理(类似 Unix 管道):map、filter、生成器表达式可嵌套组合,每个环节只保留当前项,内存占用恒定。










