Python __next__ 方法
最后修改于 2025 年 4 月 8 日
本综合指南探讨了 Python 的 __next__ 方法,这是 Python 中迭代的特殊方法。我们将介绍迭代协议、自定义迭代器、生成器和实际示例。
基本定义
__next__ 方法是 Python 迭代器协议的一部分。它从迭代器返回下一个项目。当没有更多项目可用时,它会引发 StopIteration 异常。
主要特征:它不接受参数(除了 self),返回序列中的下一个值,并在调用之间维护内部状态。它与 __iter__ 协同工作以实现完整的迭代协议。
基本迭代器实现
这是一个简单的迭代器类,实现了 __iter__ 和 __next__ 方法。这演示了基本的迭代器模式。
class CountUpTo:
def __init__(self, max):
self.max = max
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current >= self.max:
raise StopIteration
self.current += 1
return self.current - 1
counter = CountUpTo(5)
for num in counter:
print(num) # Prints 0 1 2 3 4
此迭代器从 0 向上计数到(但不包括)指定的最大值。__next__ 方法递增计数器并返回值,直到达到限制。
__iter__ 方法返回 self,使该对象既是迭代器又是可迭代对象。这对于简单的迭代器来说很常见。
无限迭代器
迭代器不必是有限的。此示例显示了一个无限迭代器,它无限期地生成斐波那契数。
class Fibonacci:
def __init__(self):
self.a, self.b = 0, 1
def __iter__(self):
return self
def __next__(self):
result = self.a
self.a, self.b = self.b, self.a + self.b
return result
fib = Fibonacci()
for i, num in enumerate(fib):
print(num)
if i >= 9: # Print first 10 numbers
break
这个斐波那契迭代器永远不会引发 StopIteration,使其成为无限迭代器。我们使用 break 条件在外部控制迭代。
状态(当前的斐波那契数)在 __next__ 调用之间的实例变量中维护。这演示了有状态的迭代。
文件行迭代器
这个实际的示例创建了一个迭代器,它懒惰地从文件中读取行,这对于大型文件来说是内存高效的。
class FileLineIterator:
def __init__(self, filename):
self.file = open(filename)
def __iter__(self):
return self
def __next__(self):
line = self.file.readline()
if not line:
self.file.close()
raise StopIteration
return line.strip()
def __del__(self):
if hasattr(self, 'file') and self.file:
self.file.close()
lines = FileLineIterator('data.txt')
for line in lines:
print(line)
此迭代器一次从文件中读取一行,仅将所需的加载到内存中。它在迭代完成时正确关闭文件。
如果迭代器在完成之前被垃圾回收,则 __del__ 方法确保文件被关闭。这对于资源清理非常重要。
链式迭代器
此示例演示如何使用 __next__ 将多个迭代器链接在一起,从而创建一个单一的连续序列。
class ChainIterators:
def __init__(self, *iterables):
self.iterables = iter(iterables)
self.current = iter(next(self.iterables))
def __iter__(self):
return self
def __next__(self):
try:
return next(self.current)
except StopIteration:
self.current = iter(next(self.iterables))
return next(self.current)
chained = ChainIterators([1, 2, 3], 'abc', (4.5, 6.7))
for item in chained:
print(item) # Prints 1, 2, 3, 'a', 'b', 'c', 4.5, 6.7
此迭代器将多个序列链接在一起,在每个序列耗尽时无缝地从一个序列过渡到下一个序列。它处理任何可迭代的输入。
该实现使用嵌套的迭代器,捕获当前迭代器的 StopIteration 以移动到序列中的下一个迭代器。
具有重置功能的有状态迭代器
这个高级示例展示了一个可以重置为其初始状态的迭代器,展示了更复杂的 __next__ 行为。
class ResettableRange:
def __init__(self, start, stop):
self.start = start
self.stop = stop
self.reset()
def reset(self):
self.current = self.start
def __iter__(self):
return self
def __next__(self):
if self.current >= self.stop:
raise StopIteration
result = self.current
self.current += 1
return result
ranger = ResettableRange(2, 5)
print(list(ranger)) # [2, 3, 4]
ranger.reset()
print(list(ranger)) # [2, 3, 4] again
此迭代器模仿 range 行为,但添加了一个 reset 方法来从头开始重新启动迭代。状态被维护,但可以根据需要重置。
reset 方法演示了如何从外部管理迭代器状态,从而提供对迭代行为的更多控制。
最佳实践
- 始终引发 StopIteration 异常: 当没有更多项目可用时
- 小心维护状态: 确保调用之间行为一致
- 实现 __iter__: 使您的迭代器正确地可迭代
- 考虑内存使用情况: 迭代器应该是内存高效的
- 记录行为: 清楚地记录迭代行为和限制
资料来源
作者
列出所有 Python 教程。