>>>PyPathPython 学习站
首页›核心篇›kp-012
核心篇 · Core lv.2 核心 kp-012

迭代器协议

前置知识:kp-006、kp-009

1. 一句话定义

可迭代对象实现 __iter__ 返回迭代器;迭代器额外实现 __next__ 逐个吐值,耗尽抛 StopIteration——for 循环、解包、推导式全部建立在这套协议上。

2. 为什么重要

这是 Python"鸭子类型"(kp-019)的经典舞台:不关心对象是什么类型,只关心它会不会 next()。理解协议后,for/推导式/生成器/asyncio 看起来不再是四个孤立特性,而是同一思想的四层展开。

3. 前置知识

kp-006(for 循环的表层用法)。

4. 核心概念

  • Iterable(可迭代):有 __iter__;可反复迭代(每次返回新迭代器)。
  • Iterator(迭代器):有 __iter__(返回自身)+ __next__;一次性,耗尽即空。
  • 关系:list 是 iterable 不是 iterator;调用 iter(list) 得到它的 iterator。

5. 原理与机制

python
it = iter([10, 20])
next(it)     # 10
next(it)     # 20
next(it)     # StopIteration

# for x in obj 等价于:
_it = iter(obj)
while True:
    try:
        x = next(_it)
    except StopIteration:
        break
    ...  # 循环体

自定义迭代器:

python
class Countdown:
    def __init__(self, n): self.n = n
    def __iter__(self): return self
    def __next__(self):
        if self.n <= 0:
            raise StopIteration
        self.n -= 1
        return self.n + 1

内置工具:zip 并行迭代(短者止)、enumerate 带下标、reversed、iter(callable, sentinel) 的哨兵模式。

6. 关键事实(模型/图示)

text
Iterable ──iter()──► Iterator ──next()──► 值 … ──► StopIteration
                          ▲
for / zip / list() / 解包 / max min sum  全都在调这一对函数

zip 与 map 返回的就是迭代器——"惰性"在标准库无处不在。

7. 直观类比

iterable 是一本书(可以反复从第一页读起),iterator 是书签:它记住读到哪了,只能前进不能后退,读完(StopIteration)这本书签就作废。你不会对书签说"翻回第一页"——那要重新开一本(重新 iter())。

8. 实例与案例

python
names = ["a", "b"]; scores = [90, 80]
for n, s in zip(names, scores):
    print(n, s)

# 迭代器的一次性坑
it = iter([1, 2, 3])
sum(it)      # 6
sum(it)      # 0 !已耗尽

9. 常见误区

  1. 对迭代器二次消费(上例)—— 判断与遍历共用同一个生成器/迭代器是经典 bug;要复用先 list() 具体化。
  2. 把"可 for"与"是 list"画等号 —— 文件对象、dict.keys()、zip 结果都可 for,但不是 list,有的只能遍历一次。
  3. 以为 next() 越界返回 None —— 抛 StopIteration;可用 next(it, default) 提供默认值。

10. 自测题

  1. list 是 iterator 吗?如何得到它的 iterator?
  2. zip([1,2],[3,4,5]) 会产出几组?为什么?
  3. 自己写一个类迭代序列需要实现哪些方法?
参考答案
  1. 不是;iter(lst)。
  2. 2 组;zip 按最短的可迭代长度停止。
  3. __iter__(返回自身或新迭代器)与 __next__(吐值并最终抛 StopIteration)。

11. 与其他知识点的关系

  • kp-013 生成器:写迭代器的最省力方式。
  • kp-038 itertools:协议之上的标准工具箱。
  • kp-019 魔术方法:协议即 dunder 约定。

12. 延伸阅读

  • Python 官方文档:Iterator Types / Glossary: iterator, iterable