在 Python 中,迭代器协议(Iterator Protocol) 是实现对象可迭代的核心机制。它由两个方法组成:


迭代器协议的两个核心方法:

方法名 作用简介
__iter__(self) 返回一个迭代器对象(通常是 self
__next__(self) 返回序列中的下一个元素;如果没有更多元素,抛出 StopIteration 异常

什么是迭代器(Iterator)?

一个类如果实现了上述两个方法,就被认为是一个迭代器(符合迭代器协议)。这使得它可以被用于 for 循环、list()tuple() 等场景中。


示例 1:自定义一个简单的迭代器类

我们自定义一个迭代器,模拟 range(0, n) 的行为:

class MyRange:
    def __init__(self, end):
        self.current = 0
        self.end = end

    def __iter__(self):
        return self  # 返回迭代器对象本身

    def __next__(self):
        if self.current < self.end:
            val = self.current
            self.current += 1
            return val
        else:
            raise StopIteration  # 没有更多元素了

使用方式:

r = MyRange(5)
for i in r:
    print(i)

输出:

0
1
2
3
4

示例 2:iter()next() 内部如何工作?

r = MyRange(3)

it = iter(r)  # 调用 r.__iter__()
print(next(it))  # -> 0
print(next(it))  # -> 1
print(next(it))  # -> 2
print(next(it))  # -> StopIteration 抛出

示例 3:只实现 __iter__ 的对象不是迭代器

如果一个对象只实现了 __iter__(),那它是一个可迭代对象(Iterable),而不是迭代器。

例如:

class MyList:
    def __init__(self, data):
        self.data = data

    def __iter__(self):
        return iter(self.data)  # 返回一个真正的迭代器

这允许你使用 for 循环,但你不能直接用 next(MyList(...)),因为它没有 __next__() 方法。


示例 4:类实现斐波那契迭代器(无限序列)

class FibonacciIterator:
    def __init__(self):
        self.a = 0
        self.b = 1

    def __iter__(self):
        return self

    def __next__(self):
        value = self.a
        self.a, self.b = self.b, self.a + self.b
        return value

使用方式:

fib = FibonacciIterator()

for i, val in enumerate(fib):
    print(val)
    if i >= 9:
        break

输出:

0
1
1
2
3
5
8
13
21
34

这个版本可以无限生成斐波那契数,因为没有 StopIteration,你必须手动控制停止条件(如上用 i 计数)。


示例 5:使用生成器实现斐波那契(更简洁)

如果你不需要复杂的状态管理,用 yield 可以更简洁地实现迭代器:

def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

使用:

for i, val in enumerate(fibonacci()):
    print(val)
    if i >= 9:
        break

生成器函数自动实现了 __iter__()__next__(),符合迭代器协议,所以也可以直接用于 for


示例 6:限制长度的斐波那契类(支持 StopIteration

我们现在加个终止条件:

class Fibonacci:
    def __init__(self, max_count):
        self.max_count = max_count
        self.count = 0
        self.a, self.b = 0, 1

    def __iter__(self):
        return self

    def __next__(self):
        if self.count >= self.max_count:
            raise StopIteration

        value = self.a
        self.a, self.b = self.b, self.a + self.b
        self.count += 1
        return value

使用:

for val in Fibonacci(10):
    print(val)

输出:

0
1
1
2
3
5
8
13
21
34

总结:类 vs 生成器实现迭代器

特性 类方式 (__iter__, __next__) 生成器 (yield)
状态变量灵活、控制细致 ✔️ 一定程度上可以
代码简洁、逻辑清晰 ❌(需手动维护状态) ✔️(自动保存上下文)
无限序列 / 惰性计算 ✔️(手动管理) ✔️(天然支持)
更适合复杂的数据结构遍历 ✔️(如树、图的自定义遍历器) 一般 ❌

建议使用场景

  • 自定义数据结构(如树、图)遍历时
  • 惰性计算(如读取大文件)
  • 实现无限序列(如斐波那契数列)

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐