Iterator
每个 Iterator 类都有一个 _next_() 函数, 比如 file 是一个 Iterator
f = open('./foo.py')
f.__next__()
f.__next__()
会输出 foo.py 的前两行
Iterable
每个 Iterable 类都可以通过 iter() 函数获得其对应的 Iterator, 比如列表, 字典都是 Iterable ( file 不仅是 iterator, 也是 iterable)
a = [1, 2, 3]
it_a = iter(a)
it_a.__next__() # 输出 1
it_a.__next__() # 输出 2
也就是说, 可迭代的类都是 Iterable, 它的迭代功能通过可以被 iter() 函数调用来实现. 至于为什么要将迭代功能分离成 Iterator 和 Iterable 两个类, 我认为主要原因有两个:
- 为了支持并发迭代: 即每个迭代器都维护一个当前迭代位置的指针, 这样就允许在同一时刻对同一对象存在多个不同位置的迭代.
- 分离了功能逻辑, 因为如果一个容器本身是 Iterator, 那么它必须维护一个迭代位置的指针, 但是这个指针与其实现逻辑并不相关. 比如对于一个链表类, 它只希望维护头结点指针, 长度等与其相关的成员变量, 对于迭代相关的变量最好还是分离到其他类中比较好.
for 循环
python 的 for 语句也是语法糖, 以下两种表达等价
a = [1, 2, 3]
# 方式一
for i in a:
# 循环体
print(i)
# 方式二
iter_a = iter(a)
while True:
try:
i = iter.__next__()
#循环体
print(i)
except StopIteration:
break