Python __iter__ 方法
最后修改于 2025 年 4 月 8 日
本综合指南探讨 Python 的 __iter__
方法,该特殊方法使对象可迭代。我们将介绍迭代协议、自定义迭代器、生成器函数和实际示例。
基本定义
__iter__
方法返回一个实现迭代协议的迭代器对象。当需要迭代对象时,例如在 for
循环中,会调用它。
主要特点:它必须返回一个迭代器对象(该对象实现 __next__
),启用对容器对象的迭代,并与 Python 的内置 iter()
函数一起使用。
基本 __iter__ 实现
这是一个简单的实现,展示了 __iter__
如何使类可迭代。该示例演示了迭代的最低要求。
class MyIterable: def __init__(self, data): self.data = data def __iter__(self): return iter(self.data) items = MyIterable([1, 2, 3]) for item in items: print(item)
此示例将迭代委托给内置的列表迭代器。 __iter__
方法返回内部数据列表的迭代器。
iter()
函数在底层调用 __iter__
。这是使对象与 for
循环一起使用的标准方法。
自定义迭代器类
我们可以通过实现 __iter__
和 __next__
方法来创建自定义迭代器。这可以完全控制迭代行为。
class CountDown: def __init__(self, start): self.current = start self.start = start def __iter__(self): return self def __next__(self): if self.current < 0: raise StopIteration else: result = self.current self.current -= 1 return result for num in CountDown(5): print(num)
这个倒计时迭代器返回从 start 到 0 的数字。由于该类本身就是一个迭代器,因此 __iter__
返回 self。
__next__
方法控制迭代逻辑,并在完成时引发 StopIteration
。这是迭代器协议的要求。
生成器函数作为 __iter__
我们可以使用 __iter__
中的生成器函数,而不是单独的迭代器类。 这通常更简洁易读。
class Squares: def __init__(self, limit): self.limit = limit def __iter__(self): for i in range(1, self.limit + 1): yield i * i for square in Squares(5): print(square)
此示例生成数字的平方,直到达到限制。 __iter__
方法使用 yield
自动创建生成器迭代器。
生成器函数通过自动处理 __next__
和状态管理来简化迭代器实现。它们也节省内存。
迭代自定义数据结构
__iter__
对于自定义数据结构特别有用,您希望控制在迭代期间如何访问元素。
class TreeNode: def __init__(self, value, left=None, right=None): self.value = value self.left = left self.right = right def __iter__(self): if self.left: yield from self.left yield self.value if self.right: yield from self.right tree = TreeNode(4, TreeNode(2, TreeNode(1), TreeNode(3)), TreeNode(6, TreeNode(5), TreeNode(7)) ) for value in tree: print(value) # Prints 1-7 in order
此二叉树通过 __iter__
实现中序遍历。 yield from
以递归方式委托给子节点的迭代器。
这种模式适用于任何树状结构,您希望在简单的迭代界面后面隐藏遍历的复杂性。
使用 __iter__ 进行惰性求值
__iter__
可以实现惰性求值,在这种求值中,值仅在迭代期间需要时才计算,从而节省内存和 CPU 周期。
class Fibonacci: def __iter__(self): a, b = 0, 1 while True: yield a a, b = b, a + b import itertools for fib in itertools.islice(Fibonacci(), 10): print(fib)
这个斐波那契数列生成器按需计算数字。 为了演示,无限序列可以安全地与 itertools.islice
一起使用。
对于大型或无限序列,惰性求值非常强大,因为预先计算所有值是不切实际或不可能的。
最佳实践
- 返回一个新的迭代器: 每个
__iter__
调用都应该返回一个新的迭代器 - 实现两种协议: 对于自定义迭代器,同时实现
__iter__
和__next__
- 考虑使用生成器: 生成器函数通常简化迭代器实现
- 正确处理状态: 确保每次新迭代都重置迭代器状态
- 使用 StopIteration: 使用
StopIteration
正确指示迭代完成
资料来源
作者
列出所有 Python 教程。