Python 迭代器协议
迭代器协议是 Python 迭代机制的核心规范,定义迭代器的行为。
协议组成
迭代器协议包含两个方法:
__iter__:返回迭代器对象__next__:返回下一个元素,结束时抛出StopIteration
for 循环工作原理
for 循环内部调用迭代器协议:
Python
# for 循环
for item in iterable:
print(item)
# 等价于
iterator = iter(iterable) # 调用 __iter__
while True:
try:
item = next(iterator) # 调用 __next__
print(item)
except StopIteration:
break
可迭代对象 vs 迭代器
Python
# 可迭代对象:实现 __iter__,返回迭代器
class MyIterable:
def __init__(self, data):
self.data = data
def __iter__(self):
return MyIterator(self.data)
# 迭代器:实现 __iter__ 和 __next__
class MyIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
return self # 返回自身
def __next__(self):
if self.index >= len(self.data):
raise StopIteration
value = self.data[self.index]
self.index += 1
return value
# 使用
iterable = MyIterable([1, 2, 3])
for item in iterable:
print(item)
iter() 函数
iter() 函数触发 __iter__ 方法:
Python
# 对可迭代对象调用 iter()
lst = [1, 2, 3]
it = iter(lst) # 返回列表迭代器
# 对迭代器调用 iter()
print(it is iter(it)) # True(迭代器的 __iter__ 返回自身)
# iter() 的第二种用法:双参数形式
counter = iter(lambda: int(input("输入数字: ")), 0)
# 每次调用函数,直到返回 0 时停止
next() 函数
next() 函数触发 __next__ 方法:
Python
lst = [1, 2, 3]
it = iter(lst)
print(next(it)) # 1
print(next(it)) # 2
print(next(it)) # 3
print(next(it)) # StopIteration
# 提供默认值避免异常
print(next(it, 'end')) # 'end'(不抛异常)
检查迭代器
Python
from collections.abc import Iterator, Iterable
# 检查是否可迭代
lst = [1, 2, 3]
print(isinstance(lst, Iterable)) # True
# 检查是否是迭代器
it = iter(lst)
print(isinstance(it, Iterator)) # True
# 列表是可迭代对象,但不是迭代器
print(isinstance(lst, Iterator)) # False
迭代器特点
一次性消耗
Python
lst = [1, 2, 3]
it = iter(lst)
print(list(it)) # [1, 2, 3]
print(list(it)) # [](迭代器已耗尽)
# 原始列表不受影响
print(lst) # [1, 2, 3]
print(list(iter(lst))) # [1, 2, 3](新迭代器)
惰性计算
迭代器只在需要时计算下一个值:
Python
def lazy_range(n):
"惰性生成器"
i = 0
while i < n:
yield i # 只在调用 next 时计算
i += 1
gen = lazy_range(1000000) # 不立即计算
print(next(gen)) # 0(计算第一个值)
内置迭代器类型
Python
# 列表迭代器
lst = [1, 2, 3]
print(type(iter(lst))) # list_iterator
# 字典迭代器
d = {'a': 1, 'b': 2}
print(type(iter(d))) # dict_keyiterator
print(type(iter(d.values()))) # dict_valueiterator
print(type(iter(d.items()))) # dict_itemiterator
# 字符串迭代器
s = "abc"
print(type(iter(s))) # str_iterator
# 文件迭代器
f = open('data.txt')
print(type(iter(f))) # TextIOWrapper(文件对象本身就是迭代器)
手动实现协议
Python
class Countdown:
"倒计时迭代器"
def __init__(self, start):
self.current = start
def __iter__(self):
return self
def __next__(self):
if self.current <= 0:
raise StopIteration
value = self.current
self.current -= 1
return value
# 使用 for 循环
for num in Countdown(5):
print(num) # 5, 4, 3, 2, 1
# 手动迭代
cd = Countdown(3)
while True:
try:
print(next(cd))
except StopIteration:
break
协议验证示例
Python
def verify_iterator(obj):
"验证是否遵循迭代器协议"
# 检查方法存在
if not hasattr(obj, '__iter__'):
return False, "缺少 __iter__ 方法"
if not hasattr(obj, '__next__'):
return False, "缺少 __next__ 方法"
# 检查 __iter__ 返回自身
if iter(obj) is not obj:
return False, "__iter__ 未返回自身"
return True, "符合迭代器协议"
class GoodIterator:
def __iter__(self):
return self
def __next__(self):
raise StopIteration
class BadIterator:
def __iter__(self):
return None # 错误:未返回迭代器
def __next__(self):
return 1
print(verify_iterator(GoodIterator())) # (True, '符合迭代器协议')
print(verify_iterator(BadIterator())) # (False, '__iter__ 未返回自身')
协议流程图
text
for item in iterable:
↓ 调用 iter(iterable)
↓ 触发 iterable.__iter__()
↓ 返回迭代器 iterator
↓ 循环调用 next(iterator)
↓ 触发 iterator.__next__()
↓ 返回下一个元素
↓ 当 __next__ 抛出 StopIteration
↓ 循环结束
要点总结
| 方法 | 作用 | 返回值 |
|---|---|---|
__iter__ | 返回迭代器 | 迭代器对象(通常返回 self) |
__next__ | 返回下一元素 | 元素值或抛出 StopIteration |
| 类型 | 协议要求 | 特点 |
|---|---|---|
| 可迭代对象 | 只需 __iter__ | 可多次迭代 |
| 迭代器 | __iter__ + __next__ | 一次性消耗 |
迭代器协议是 Python 迭代机制的基石,理解
__iter__和__next__有助于掌握 for 循环原理。
D:\git2\jwdev\articles\PYTHON\进阶\迭代器与生成器\迭代器协议.md
📝 发现内容有误?点击此处直接编辑