Iterable |
"我是可以被遍历的"。它是一个容器,实现了 __iter__() 方法,该方法返回一个迭代器。 |
Iterator |
"我负责具体的遍历工作"。它是一个有状态的对象,实现了 __next__() 方法来返回下一个值,并且也实现了 __iter__() 方法(通常返回self )。 |
天生是 Iterable(但不是 Iterator):
list
, tuple
, str
, dict
, set
, frozenset
, range
天生就是 Iterator(因此也是 Iterable):
生成器、enumerate
、zip
、map
、filter
、文件对象、各种迭代器
法则1:看创建方式
用字面量或构造函数创建的 → 通常是 Iterable 但不是 Iterator
[]
, ()
, {}
, set()
, range()
, dict()
用函数或表达式创建的 → 通常就是 Iterator
iter()
, enumerate()
, zip()
, map()
, filter()
, 生成器表达式
这种区分是有意为之的设计:
Iterable
类型:专注于数据存储和组织结构
如:list
管理有序集合,dict
管理键值映射
应该可重用、可多次访问
Iterator
类型:专注于数据处理和流转
如:map
进行数据转换,filter
进行数据过滤
通常代表计算过程,具有一次性特性
你在代码里写的到底是 哪个 Iterable/Iterator,得看你具体写了什么:
1. 如果你写的是
from collections.abc import Iterable, Iterator
那它们就是 collections.abc 里的两个抽象基类(ABC)。
作用:
◦ 用来判断某个对象是否“可迭代”或“是迭代器”(isinstance(obj, Iterable))。
◦ 用来继承(class Foo(Iterable): ...),强制子类实现协议方法。
2. 如果你写的是
from typing import Iterable, Iterator
那么它们其实是泛型别名,底层最终指向的也是 collections.abc.Iterable / Iterator,但主要用在类型注解里,例如:
def func(xs: Iterable[int]) -> Iterator[str]:
...
3. 如果你根本没有写导入语句,只是口头或文档里说 “这个函数返回一个 Iterator”,那它通常指“符合迭代器协议的任意对象”,并不特指 collections.abc.Iterator。