必须同时实现__iter__和__next__,且__iter__须返回自身或新迭代器;若仅返回self而不重置状态,多次遍历会失败;__next__必须显式raise stopiteration,不可用return终止。

直接说结论:必须同时实现 __iter__ 和 __next__,且 __iter__ 必须返回自身(或另一个迭代器对象),否则 for 循环会报 TypeError: 'X' object is not iterable。
为什么 __iter__ 不能只返回 self 就完事?
很多初学者写完 __iter__(self): return self 就以为搞定了,结果发现多次遍历失败——比如在同一个对象上连续执行两次 for 循环,第二次直接空跑。这是因为迭代器协议要求:迭代器对象本身必须可被 iter() 调用,且每次调用都应返回一个“新鲜的”迭代状态。如果 __iter__ 总是返回 self,而 __next__ 又修改了内部状态(如索引 self._i += 1),那第二次遍历就会从上次中断处继续,甚至直接抛 StopIteration。
解决办法是让 __iter__ 返回一个新的迭代器实例,或者在 __iter__ 中重置状态:
- 推荐做法:在
__iter__里重置计数器(如self._i = 0),再返回self—— 简单、符合直觉,适用于单次使用场景 - 更严谨做法:把迭代逻辑拆到独立类中,
__iter__每次都return IteratorClass(self.data)—— 支持多路并发遍历,比如两个for循环同时跑
__next__ 必须手动抛 StopIteration,不能靠 return
这是最常踩的坑:__next__ 函数末尾没写 raise StopIteration,或者用 return None 代替,会导致无限循环或静默失败。Python 迭代协议明确规定:迭代结束的唯一信号是 StopIteration 异常,return 任何值(包括 None)都会被当作有效元素返回。
典型错误写法:
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
def __next__(self):
if self._i >= len(self.data):
return # ❌ 错!这会让 for 循环永远卡住
正确写法:
def __next__(self):
if self._i >= len(self.data):
raise StopIteration # ✅ 唯一合法的终止方式
item = self.data[self._i]
self._i += 1
return item
和生成器函数比,手写 __iter__/__next__ 的实际价值在哪?
绝大多数简单场景,用 yield 写生成器函数更省事、更安全。手写双下划线方法真正有用的地方是:
- 需要精确控制状态生命周期(比如持有数据库游标、文件句柄,必须在
__del__或close()中释放) - 要实现“可重入迭代器”——即支持多次
iter(obj)调用返回彼此隔离的迭代状态 - 对接 C 扩展或底层协议(如某些异步 I/O 迭代器要求继承
collections.abc.Iterator并显式实现) - 教学/调试目的:看清迭代器底层如何与
for、list()、next()协作
注意:如果你只是想“让类支持 for”,优先考虑在 __iter__ 里 return iter(self.data) 或用 yield,别硬套双下划线。
真正麻烦的不是写对这两个方法,而是想清楚“这个对象到底该不该是迭代器,还是只该是可迭代对象”。前者要自己管理状态,后者只需返回一个迭代器——多数时候你想要的是后者。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










