结论:可迭代对象实现了 __iter__(返回一个迭代器),表示"可以被遍历";迭代器实现了 __iter__(返回自己)和 __next__(逐个产出元素,耗尽抛 StopIteration),表示"正在进行的遍历状态"。for 循环的本质是 iter(obj) 拿迭代器后反复 next 直到 StopIteration。
展开:区分意义:1)一个可迭代对象可以被多次独立遍历(list 每次 iter 得到新迭代器),迭代器是一次性的——it = iter([1,2]); list(it); list(it) 第二次得到空;2)迭代器是惰性的,只在 next 时计算,这是生成器、itertools 流式处理大数据的基础。常见判断误区:iter(x) 不报错即 iterable(__getitem__ 协议的老式序列也能被 iter 兜底);next(x) 可用才是 iterator。内置协同:zip、map、enumerate 返回迭代器(3.x 惰性化),range 是惰性序列但不是迭代器(可重复遍历,没有 __next__)。
nums = [1, 2, 3] # 可迭代
it = iter(nums) # 迭代器
print(next(it)) # 1
print(list(it)) # [2, 3] —— 迭代器被消耗
print(list(it)) # [] 一次性
易错点:函数同时实现 __iter__ 返回 self 和共享游标时,同一个对象二次遍历会从头还是继续?看实现——文件对象就是迭代器(二次遍历从当前位置继续)。追问方向:生成器如何自动满足迭代器协议、for-else 的 else 何时执行。