Python 迭代器与可迭代对象原理:从协议实现到高阶应用
一、深入理解迭代机制
1.1 迭代器协议核心
Python的迭代机制建立在__iter__和__next__双方法协议之上,其运作原理如下:
class MyRangeIterator:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current >= self.end:
raise StopIteration
value = self.current
self.current += 1
return value
代码解析:
__iter__返回迭代器自身,符合迭代器协议__next__实现核心逻辑,控制迭代终止条件- StopIteration异常是迭代终止的标准信号
注意事项:
- 迭代器只能单向前进,不可重置
- 同一个迭代器实例无法被多个循环共享
- 迭代结束后再次调用next()会持续抛出StopIteration
1.2 可迭代对象本质
可迭代对象与迭代器的关键区别在于:
| 特性 | 可迭代对象 | 迭代器 |
|---|---|---|
| 实现方法 | 仅需__iter__ | 需要__iter__和__next__ |
| 状态保持 | 无状态 | 维护迭代状态 |
| 复用性 | 可多次迭代 | 单次耗尽 |
| 内存占用 | 可能较大 | 通常较小 |
典型可迭代对象实现:
class MyRangeIterable:
def __init__(self, start, end):
self.start = start
self.end = end
def __iter__(self):
return MyRangeIterator(self.start, self.end)
二、惰性计算实践
2.1 自定义高效生成器
实现支持步长的惰性生成器:
class AdvancedRange:
def __init__(self, start, end=None, step=1):
if end is None:
start, end = 0, start
self.start = start
self.end = end
self.step = step
def __iter__(self):
current = self.start
while current < self.end:
yield current
current += self.step
# 使用示例
for num in AdvancedRange(1, 1000000, 2):
if num > 100:
break # 实际仅生成到101即终止
核心优势:
- 首先生成算法复杂度为O(1)
- 内存占用恒定,与范围大小无关
- 支持提前终止迭代,避免无效计算
2.2 生成器表达式
Python提供更简洁的生成器语法:
# 生成器表达式
cubes = (x**3 for x in range(10**6)
# 等效的生成器函数
def generate_cubes():
for x in range(10**6):
yield x**3
最佳实践:
- 数据量 > 1MB时优先使用生成器
- 多次遍历需求应转换为容器类型
- 注意生成器的单次消费特性
三、itertools模块高阶应用
3.1 无限迭代器妙用
import itertools
# 无限ID生成器
def id_generator(prefix):
counter = itertools.count(1)
while True:
yield f"{prefix}{next(counter)}"
# 应用示例
user_gen = id_generator("USER_")
print(next(user_gen)) # USER_1
print(next(user_gen)) # USER_2
3.2 迭代器组合技
# 多级数据处理管道
def data_pipeline():
# 阶段1:数据生成
raw_data = itertools.islice(itertools.count(), 1000)
# 阶段2:数据过滤
filtered = filter(lambda x: x % 3 == 0, raw_data)
# 阶段3:数据转换
transformed = map(lambda x: x**2, filtered)
# 阶段4:结果分块
return iter(lambda: list(itertools.islice(transformed, 10)), [])
# 分批获取处理结果
batch_gen = data_pipeline()
for _ in range(3):
print(next(batch_gen)) # 每次输出10个元素
四、内存优化与性能测试
4.1 内存占用对比
import sys
# 列表推导式
list_data = [x for x in range(10**6)]
print(sys.getsizeof(list_data)) # 约8.4MB
# 生成器
gen_data = (x for x in range(10**6))
print(sys.getsizeof(gen_data)) # 约128B
4.2 性能基准测试
使用timeit模块进行性能分析:
import timeit
# 列表处理
list_time = timeit.timeit(
'sum([x**2 for x in range(100000)])',
number=100
)
# 生成器处理
gen_time = timeit.timeit(
'sum((x**2 for x in range(100000)))',
number=100
)
print(f"List time: {list_time:.3f}s")
print(f"Generator time: {gen_time:.3f}s")
典型结果:
- 小数据量(<1k):列表更快
- 大数据量(>10k):生成器优势明显
- 内存受限场景:生成器唯一选择
五、企业级应用实践
5.1 数据库流式读取
import psycopg2
from itertools import islice
class DatabaseStream:
def __init__(self, query, batch_size=1000):
self.conn = psycopg2.connect(...)
self.cursor = self.conn.cursor()
self.cursor.execute(query)
self.batch_size = batch_size
def __iter__(self):
while True:
rows = self.cursor.fetchmany(self.batch_size)
if not rows:
self.conn.close()
return
yield from rows
# 使用示例
stream = DatabaseStream("SELECT * FROM billion_row_table")
for row in islice(stream, 10000):
process_row(row) # 仅加载处理所需数据
5.2 异步迭代器
Python 3.6+支持异步迭代协议:
import aiohttp
class AsyncWebCrawler:
def __init__(self, urls):
self.urls = urls
def __aiter__(self):
self.index = 0
return self
async def __anext__(self):
if self.index >= len(self.urls):
raise StopAsyncIteration
async with aiohttp.ClientSession() as session:
async with session.get(self.urls[self.index]) as response:
result = await response.text()
self.index += 1
return result
# 使用示例
async for content in AsyncWebCrawler(url_list):
parse_content(content)
六、深度练习题
6.1 无限斐波那契迭代器
class FibonacciInfinity:
def __init__(self):
self.a, self.b = 0, 1
def __iter__(self):
return self
def __next__(self):
value = self.a
self.a, self.b = self.b, self.a + self.b
return value
# 验证实现
fib = FibonacciInfinity()
print([next(fib) for _ in range(10)]) # [0,1,1,2,3,5,8,13,21,34]
6.2 迭代器适配器
实现类似RxJS的观察者模式:
class IteratorAdapter:
def __init__(self, iterable):
self.iterator = iter(iterable)
self.subscribers = []
def subscribe(self, callback):
self.subscribers.append(callback)
def __iter__(self):
for item in self.iterator:
for callback in self.subscribers:
callback(item)
yield item
# 使用示例
adapter = IteratorAdapter(range(5))
adapter.subscribe(lambda x: print(f"Log: {x}"))
adapter.subscribe(lambda x: print(f"Double: {x*2}"))
list(adapter) # 触发所有回调
结语
掌握迭代器协议是成为Python高级开发者的必经之路。本文从基础实现到企业级应用,揭示了迭代器在数据处理、内存优化和异步编程中的核心价值。建议读者通过实现自定义迭代器、优化现有代码中的迭代逻辑来深化理解。记住:好的迭代器设计能让程序既优雅又高效!
扩展阅读方向:
- 生成器协程(yield from语法)
- 迭代器模式在设计模式中的应用
- PEP 525 异步生成器规范
- 函数式编程中的惰性求值
1371

被折叠的 条评论
为什么被折叠?



