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 教程。