本文目录导读:

我来详细介绍Python中自定义迭代器的几种实现方式。
使用类实现迭代器(iter 和 next)
class MyRange:
"""自定义范围迭代器"""
def __init__(self, start, end, step=1):
self.current = start
self.end = end
self.step = step
def __iter__(self):
# 返回迭代器对象本身
return self
def __next__(self):
# 检查是否还有下一个元素
if self.current >= self.end:
raise StopIteration
value = self.current
self.current += self.step
return value
# 使用示例
my_range = MyRange(0, 10, 2)
for num in my_range:
print(num, end=' ') # 输出: 0 2 4 6 8
使用生成器函数
def fibonacci_generator(n):
"""斐波那契数列生成器"""
a, b = 0, 1
count = 0
while count < n:
yield a
a, b = b, a + b
count += 1
# 使用示例
for num in fibonacci_generator(10):
print(num, end=' ') # 输出: 0 1 1 2 3 5 8 13 21 34
可迭代对象 + 独立迭代器类
class Book:
"""书籍类"""
def __init__(self, title, author):
self.title = title
self.author = author
def __str__(self):
return f"《{self.title}》- {self.author}"
class Bookshelf:
"""书架类 - 可迭代对象"""
def __init__(self):
self.books = []
def add_book(self, book):
self.books.append(book)
def __iter__(self):
# 返回一个新的迭代器实例
return BookshelfIterator(self.books)
class BookshelfIterator:
"""书架迭代器"""
def __init__(self, books):
self.books = books
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index >= len(self.books):
raise StopIteration
book = self.books[self.index]
self.index += 1
return book
# 使用示例
shelf = Bookshelf()
shelf.add_book(Book("Python编程", "张三"))
shelf.add_book(Book("数据科学", "李四"))
shelf.add_book(Book("机器学习", "王五"))
for book in shelf:
print(book)
# 输出:
# 《Python编程》- 张三
# 《数据科学》- 李四
# 《机器学习》- 王五
带状态的复杂迭代器
class CircularBuffer:
"""循环缓冲区迭代器"""
def __init__(self, size):
self.size = size
self.buffer = [None] * size
self.position = 0
self.count = 0
def add(self, item):
self.buffer[self.position] = item
self.position = (self.position + 1) % self.size
self.count = min(self.count + 1, self.size)
def __iter__(self):
return CircularBufferIterator(self.buffer, self.position, self.count)
class CircularBufferIterator:
def __init__(self, buffer, position, count):
self.buffer = buffer
self.position = position
self.count = count
self.index = 0
# 计算实际起始位置
if count < len(buffer):
self.start = 0
else:
self.start = position
def __iter__(self):
return self
def __next__(self):
if self.index >= self.count:
raise StopIteration
idx = (self.start + self.index) % len(self.buffer)
value = self.buffer[idx]
self.index += 1
return value
# 使用示例
buffer = CircularBuffer(5)
for i in range(7):
buffer.add(f"item{i}")
print("缓冲区内容:", end=' ')
for item in buffer:
print(item, end=' ') # 输出: item2 item3 item4 item5 item6
双向迭代器
class BidirectionalIterator:
"""支持双向迭代的迭代器"""
def __init__(self, data):
self.data = data
self.index = -1 # 初始位置在开始之前
def __iter__(self):
return self
def __next__(self):
self.index += 1
if self.index >= len(self.data):
raise StopIteration
return self.data[self.index]
def previous(self):
"""向前迭代"""
self.index -= 1
if self.index < 0:
self.index = 0
raise StopIteration
return self.data[self.index]
def reset(self):
"""重置迭代器"""
self.index = -1
# 使用示例
data = [10, 20, 30, 40, 50]
iterator = BidirectionalIterator(data)
print("正向迭代:")
for item in iterator:
print(item, end=' ') # 输出: 10 20 30 40 50
print("\n反向迭代:")
try:
while True:
item = iterator.previous()
print(item, end=' ') # 输出: 40 30 20 10
except StopIteration:
pass
实战示例:分页迭代器
class PaginatedAPI:
"""模拟分页API的迭代器"""
def __init__(self, total_items, page_size=5):
self.total_items = total_items
self.page_size = page_size
self.current_page = 0
self.current_index = 0
def __iter__(self):
return self
def __next__(self):
# 检查是否需要加载下一页
if self.current_index >= min(
(self.current_page + 1) * self.page_size,
self.total_items
):
self.current_page += 1
self._load_page()
# 检查是否还有数据
if self.current_page * self.page_size >= self.total_items:
raise StopIteration
# 返回当前项目
item = self._get_item(self.current_index)
self.current_index += 1
return item
def _load_page(self):
"""模拟加载页面数据"""
if self.current_page * self.page_size < self.total_items:
print(f"加载第 {self.current_page + 1} 页...")
def _get_item(self, index):
"""模拟获取项目"""
return f"项目_{index + 1}"
# 使用示例
api = PaginatedAPI(12, page_size=5)
for item, count in enumerate(api, 1):
print(f"第{count}个: {item}")
# 输出会显示3次页面加载过程
-
必须实现的方法:
__iter__():返回迭代器对象__next__():返回下一个元素,无元素时抛出StopIteration
-
生成器优势:
- 更简洁的语法
- 自动管理状态
- 适用于简单场景
-
类和独立迭代器优缺点:
- 类实现:适合简单迭代
- 独立迭代器:支持多个并行迭代
-
注意事项:
- 迭代器通常是一次性的
- 如果需要在多个地方同时迭代,使用独立迭代器对象
- 适当处理边界情况和异常
根据你的具体需求选择最合适的实现方式!