下面我们逐步分析 迭代器实现的代码,帮助你理解每个部分的作用和迭代器的工作原理。
示例代码
class MyIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
return self # 返回迭代器本身
def __next__(self):
if self.index < len(self.data): # 检查是否还有元素
result = self.data[self.index]
self.index += 1
return result
else:
raise StopIteration # 没有元素时抛出异常
详细解释
1. 类的定义
class MyIterator:
• 迭代器是一个类:这是自定义迭代器的入口,MyIterator 是我们定义的一个类。
• 它模拟了 Python 内置迭代器的行为(如列表迭代器)。
2. 初始化方法:init
def __init__(self, data):
self.data = data
self.index = 0
• init 是构造方法,在创建对象时会自动调用。
• 参数:
• data:传入的数据(可以是列表、字符串、元组等可迭代对象)。
• self.index:初始化为 0,用来跟踪当前迭代的位置。
作用:
• 存储要迭代的数据(self.data)。
• 准备一个索引(self.index)来记录迭代的位置。
例如:
my_iter = MyIterator([1, 2, 3, 4])
此时:
• self.data = [1, 2, 3, 4]
• self.index = 0
3. iter 方法
def __iter__(self):
return self # 返回迭代器本身
• iter 方法是 Python 的协议方法(定义了对象是可迭代的)。
• 返回值:
• 返回 self,即当前的迭代器对象。
• for 循环需要调用此方法来获取迭代器。
解释:
• 当你对一个对象调用 iter(obj) 或在 for 循环中时,Python 会调用 iter 方法。
• 返回当前对象本身表明这个类也是一个迭代器。
4. next 方法
def __next__(self):
if self.index < len(self.data): # 检查索引是否超出范围
result = self.data[self.index] # 获取当前索引的数据
self.index += 1 # 将索引移动到下一项
return result
else:
raise StopIteration # 如果迭代完成,抛出异常
• next 方法定义了迭代器的核心逻辑:如何获取下一个值。
• 工作流程:
- 检查索引范围:通过 self.index < len(self.data) 检查是否还有未迭代的值。
- 获取当前值:从 self.data[self.index] 获取当前索引的数据。
- 移动索引:self.index += 1 将索引移动到下一项,为下一次迭代做准备。
- 返回值:将当前值返回。
- 停止迭代:如果索引超出范围,抛出 StopIteration 异常,结束迭代。
例如:
my_iter = MyIterator([1, 2, 3])
print(next(my_iter)) # 输出 1
print(next(my_iter)) # 输出 2
print(next(my_iter)) # 输出 3
print(next(my_iter)) # 抛出 StopIteration 异常
结合 for 循环的完整示例
Python 的 for 循环实际上会调用迭代器的 iter 和 next 方法。
初始化一个迭代器
my_iter = MyIterator([1, 2, 3, 4])
使用 for 循环遍历
for item in my_iter:
print(item)
背后的工作机制:
- 调用 iter:
• for 循环第一次执行时,自动调用 iter(my_iter)。
• Python 会调用 my_iter.iter() 方法,返回迭代器本身。 - 调用 next:
• for 循环在每次迭代时,自动调用 next(my_iter)。
• Python 会调用 my_iter.next(),获取当前值。
• 如果没有值了,抛出 StopIteration 异常,终止循环。
输出:
1
2
3
4
迭代器的优势
- 节省内存:
• 迭代器不需要一次性加载所有数据,只在需要时生成下一个值。
• 比如可以处理百万级数据而不占用大量内存。 - 灵活性:
• 自定义迭代逻辑(如跳过某些值、生成无限序列)。 - 适用场景:
• 流式数据处理。
• 文件逐行读取。
• 延迟加载(Lazy Evaluation)。
本文作者为wzzyhg,转载请注明。