本文目录导读:
让我用一个可自定义步长的等差数列案例来讲解迭代器协议,这是最清晰且实用的例子:
class StepRange:
"""自定义步长的迭代器,演示迭代器协议"""
def __init__(self, start, end, step=1):
self.start = start
self.end = end
self.step = step
# 验证参数
if step == 0:
raise ValueError("步长不能为0")
def __iter__(self):
"""返回迭代器对象本身"""
self.current = self.start # 初始化当前值
return self
def __next__(self):
"""返回下一个值,如果没有更多元素则抛出StopIteration"""
# 检查是否达到结束条件
if (self.step > 0 and self.current >= self.end) or \
(self.step < 0 and self.current <= self.end):
raise StopIteration
# 保存当前值用于返回
result = self.current
# 更新当前值
self.current += self.step
return result
# ========== 使用示例 ==========
# 1. 基本使用 - 正向迭代
print("正向迭代:")
for num in StepRange(0, 5, 1):
print(num, end=" ") # 输出: 0 1 2 3 4
print()
# 2. 自定义步长
print("\n步长为2:")
for num in StepRange(0, 10, 2):
print(num, end=" ") # 输出: 0 2 4 6 8
print()
# 3. 反向迭代
print("\n反向迭代:")
for num in StepRange(10, 0, -2):
print(num, end=" ") # 输出: 10 8 6 4 2
print()
# 4. 演示迭代器协议的底层机制
print("\n手动使用迭代器协议:")
my_range = StepRange(1, 4, 1)
iterator = iter(my_range) # 调用 __iter__()
print(next(iterator)) # 调用 __next__(),输出: 1
print(next(iterator)) # 输出: 2
print(next(iterator)) # 输出: 3
# print(next(iterator)) # 会抛出 StopIteration
为什么这个案例最好?
直观展示三个关键要素
# 迭代器协议三要素: # ① __iter__() - 返回迭代器对象 # ② __next__() - 返回下一个值或抛出StopIteration # ③ StopIteration - 信号告诉for循环停止
可见的内部状态变化
# 每一步都有明确状态:
class StepRange:
def __iter__(self):
self.current = self.start # 初始化状态
return self
def __next__(self):
# 状态变化清晰可见
result = self.current # 保存当前
self.current += self.step # 更新状态
return result
展示核心机制对比
# 普通循环 vs 迭代器协议
nums = [1, 2, 3]
# 底层实际执行的是:
iterator = iter(nums) # 调用 __iter__()
while True:
try:
value = next(iterator) # 调用 __next__()
print(value)
except StopIteration: # 捕获异常
break
# 等同于:
for value in nums:
print(value)
代码可以运行的调试技巧
# 在 __next__ 中添加调试信息
class DebugStepRange(StepRange):
def __next__(self):
print(f"当前值: {self.current}, 步长: {self.step}")
return super().__next__()
# 可以清晰看到每一步的执行
for num in DebugStepRange(0, 3, 1):
print(f"获取到: {num}")
print("---")
对比迭代器和可迭代对象
# 可迭代对象 vs 迭代器
class DataContainer: # 只有 __iter__,是可迭代对象
def __init__(self, data):
self.data = data
def __iter__(self):
return iter(self.data)
# 对比我们的 StepRange(是迭代器,同时也是可迭代对象)
# 因为它同时实现了 __iter__ 和 __next__
关键知识点总结
| 概念 | 说明 | 代码表现 |
|---|---|---|
| 迭代器协议 | 实现 __iter__() 和 __next__() |
for 循环底层调用 |
| 可迭代对象 | 实现 __iter__() |
列表、字典等 |
| 迭代器 | 实现 __iter__() 和 __next__() |
文件对象、生成器 |
| 惰性求值 | 按需生成值 | range() 不一次性生成所有值 |
这个案例的优势在于:
- 简单但完整:包含了迭代器协议的全部要素
- 实用性:是对内置
range()的改进版本 - 可视化:可以直观看到每一步的状态变化
- 可扩展:容易添加调试、分支等教学功能
通过这个案例,学生能真正理解"迭代器是啥,为啥要用,以及怎么用"。