1. 迭代协议是什么? #

2. 核心关系 #

可迭代对象 (Iterable)     有 __iter__(),可被 for 遍历
        ↓ iter() 得到
迭代器 (Iterator)         有 __iter__() + __next__(),逐个产出
        ↓
生成器 (Generator)        由 yield / (x for x in ...) 自动实现协议
概念 关键方法 特点
可迭代对象 __iter__() 返回迭代器 列表、字典、文件;可多次 for
迭代器 __iter__ + __next__ 记住位置;用完即止
生成器 自动实现上述方法 项目里最常用的迭代器

3. for 循环在做什么? #

# 可迭代对象
items = [1, 2, 3]
# 调用 __iter__() 获取迭代器
iterator = iter(items)

# 手动模拟 for 循环
while True:
    try:
        # 调用 __next__() 获取下一个元素
        x = next(iterator)
    except StopIteration:
        # 没有更多元素时结束
        break
    print(x)

4. 可迭代对象 vs 迭代器 #

from collections.abc import Iterable, Iterator

# 列表是可迭代对象
lst = [1, 2, 3]
# 获取迭代器
it = iter(lst)

# 列表是可迭代对象,但不是迭代器
print(isinstance(lst, Iterable))
print(isinstance(lst, Iterator))
# iter(lst) 返回的是迭代器
print(isinstance(it, Iterator))
列表等容器 iter(列表)、生成器
多次 for 可以 生成器/迭代器通常不行,需重建
角色 数据源 实际「一个个取」的对象

5. 生成器与协议 #

# 生成器函数
def gen():
    yield 1
    yield 2

# 调用函数返回生成器对象
g = gen()
# 逐个取出元素
print(next(g))
print(next(g))

6. 自定义可迭代 #

class MyIterable:
    def __init__(self, data):
        self.data = data

    def __iter__(self):
        self.index = 0
        return self

    def __next__(self):
        if self.index < len(self.data):
            val = self.data[self.index]
            self.index += 1
            return val
        else:
            raise StopIteration

# 创建可迭代对象并遍历
my_iterable = MyIterable([1, 2, 3, 4])
for item in my_iterable:
    print(item)

7. 项目开发要点 #

8. 总结 #

方法 / 异常 作用
__iter__() 返回迭代器,供 for 使用
__next__() 返回下一项
StopIteration 没有更多元素时结束迭代
yield 自动生成生成器,满足迭代协议