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 教程。