当前位置:首页 > Python > 正文

深入理解Python迭代器协议(从零开始掌握可迭代对象与自定义迭代器)

在Python编程中,Python迭代器协议是一个核心概念,它使得我们能够使用 for 循环遍历各种数据结构。无论你是初学者还是有一定经验的开发者,理解这个协议都能帮助你写出更优雅、高效的代码。

什么是迭代器协议?

简单来说,迭代器协议是一组规则,规定了对象如何被迭代。要使一个对象可迭代(即支持 for item in obj),它必须实现两个特殊方法:

  • __iter__():返回一个迭代器对象。
  • __next__():返回容器中的下一个元素;如果没有更多元素,则抛出 StopIteration 异常。
深入理解Python迭代器协议(从零开始掌握可迭代对象与自定义迭代器) Python迭代器协议 可迭代对象 自定义迭代器 __iter__方法 第1张

可迭代对象 vs 迭代器

很多初学者容易混淆这两个概念:

  • 可迭代对象(Iterable):实现了 __iter__() 方法的对象,如列表、元组、字符串等。它们本身不是迭代器,但可以“生成”迭代器。
  • 迭代器(Iterator):同时实现了 __iter__()__next__() 的对象,用于逐个访问元素。

实战:实现一个自定义迭代器

下面我们创建一个简单的计数器类,它从指定数字开始,每次加1,最多输出5次:

class SimpleCounter:    def __init__(self, start=0):        self.current = start        self.limit = start + 5  # 最多输出5个数字    def __iter__(self):        return self    def __next__(self):        if self.current < self.limit:            value = self.current            self.current += 1            return value        else:            raise StopIteration# 使用示例for num in SimpleCounter(3):    print(num)# 输出:# 3# 4# 5# 6# 7

在这个例子中,SimpleCounter 同时是可迭代对象迭代器,因为它自己实现了 __iter__() 并返回自身,同时也实现了 __next__()

只实现 __iter__ 的可迭代对象

有时我们希望对象是可迭代的,但不希望自己成为迭代器(例如为了支持多次遍历)。这时可以让 __iter__() 返回一个新的迭代器对象:

class Countdown:    def __init__(self, start):        self.start = start    def __iter__(self):        return CountdownIterator(self.start)class CountdownIterator:    def __init__(self, start):        self.current = start    def __iter__(self):        return self    def __next__(self):        if self.current > 0:            value = self.current            self.current -= 1            return value        else:            raise StopIteration# 使用for i in Countdown(3):    print(i)  # 输出: 3, 2, 1# 可以多次遍历!list1 = list(Countdown(3))list2 = list(Countdown(3))print(list1, list2)  # [3, 2, 1] [3, 2, 1]

总结

掌握Python迭代器协议不仅能让你理解 for 循环背后的机制,还能帮助你设计更灵活的数据结构。关键点如下:

  • 所有可被 for 遍历的对象都必须遵循可迭代对象规范。
  • 真正的迭代工作由迭代器完成,它通过 __next__() 提供下一个值。
  • 使用 __iter__ 方法可以轻松创建自己的自定义迭代器
  • 良好的设计应区分可迭代对象和迭代器,以支持多次遍历。

现在你已经掌握了 Python 中迭代的核心机制!快去尝试编写自己的可迭代类吧。