哪个Python案例最适合讲清楚迭代器协议

访客 python案例 3

本文目录导读:

  1. 为什么这个案例最好?
  2. 关键知识点总结

让我用一个可自定义步长的等差数列案例来讲解迭代器协议,这是最清晰且实用的例子:

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() 的改进版本
  • 可视化:可以直观看到每一步的状态变化
  • 可扩展:容易添加调试、分支等教学功能

通过这个案例,学生能真正理解"迭代器是啥,为啥要用,以及怎么用"。

标签: 生成器 迭代器

抱歉,评论功能暂时关闭!