Python __next__() 语法
__next__() 是 Python 的一个特殊方法(又称 “魔法方法” 或 “双下划线方法”),它用于定义当对迭代器在迭代过程(如使用 next() 函数或 for in 循环)中,如何返回下一个元素,并且在没有更多元素时发出信号。
语法:
class MyIterator:
def __next__(self):
# 如果有下一个元素,则返回该元素
# 如果没有更多元素,则抛出 StopIteration 异常
if self._has_next_element():
element = self._get_next_element()
return element
else:
raise StopIteration
说明:
__next__() 方法不接收任何参数,除了 self(实例本身)。
__next__() 方法应该返回序列中的下一个元素。当没有更多元素可供返回时,__next__() 必须抛出 StopIteration 异常,这是结束迭代的标准方式。
提示:
- 如果一个类实现了 __next__() 方法(并且通常也实现了 __iter__() 方法),那么它的实例就是 “迭代器(iterator)” 。
- 迭代器是 “有状态” 的对象,它们在每次调用 next() 时都会记住当前位置,并返回序列中的下一个元素。
- 迭代器只能向前遍历,并且通常只能遍历一次。一旦迭代器耗尽(即抛出 StopIteration),它就不能再次使用。
Python __next__() 摘要
| 属于 | Python 魔法方法 |
|---|---|
| 使用频率 | 高 |
| 官方文档 | 查看 |
| 相关方法 | __iter__() |
Python __next__() 示例
接下来,我们通过几个简单的例子来讲解一下 Python __next__() 方法是如何使用的。
示例 1:对内置迭代器使用 __next__()
fruits = ['apple', 'banana', 'cherry']
# 获取迭代器
iterator = iter(fruits)
print(type(iterator))
# 使用 next() 函数获取下一个元素
print(next(iterator))
print(next(iterator))
print(next(iterator))
# 尝试获取更多元素
try:
print(next(iterator))
except StopIteration:
print('迭代器已耗尽,没有更多元素了')
运行结果如下。
<class 'list_iterator'>
apple
banana
cherry
迭代器已耗尽,没有更多元素了
分析:
我们可以使用 iter() 函数来获取内置的可迭代对象(如列表、元组、字符串等)对应的迭代器对象。
当调用 next(iterator) 时,实际上就是调用了这个迭代器对象的 __next__() 方法,从而可以逐个获取元素。当所有元素都被获取后,__next__() 会抛出 StopIteration 异常。
示例 2:自定义计数器迭代器
class Counter:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
# 返回自身,因为这个对象本身就是迭代器
return self
def __next__(self):
# 返回下一个计数,直到达到 end
if self.current <= self.end:
value = self.current
self.current += 1
return value
else:
# 达到计数器末尾,抛出 StopIteration
raise StopIteration
# 创建计数器迭代器
counter = Counter(1, 3)
# 第 1 次循环 (会触发 __iter__(),然后是 __next__())
for num in counter:
print(num)
# 第 2 次循环 (此时迭代器已耗尽)
for num in counter:
print(num)
# 直接使用 next() 尝试
another_counter = Counter(5, 6)
print(next(another_counter))
print(next(another_counter))
try:
print(next(another_counter))
except StopIteration:
print('捕获到 StopIteration 异常')
运行结果如下。
1
2
3
5
6
捕获到 StopIteration 异常
分析:
Counter 类既是可迭代对象(实现了 __iter__()),也是迭代器对象(同时实现了 __iter__() 和 __next__()),并且 __iter__() 返回 self。
每次调用 __next__(),self.current 会递增并返回当前值,直到 self.current 超过 self.end,然后抛出 StopIteration 异常。
由于迭代器是单向的,counter 在第 1 次循环后就耗尽了,第 2 次循环不再产生任何元素。
示例 3:通过生成器实现 __next__() 行为
class MyDataStream:
def __init__(self, start, count):
self.start = start
self.count = count
def __iter__(self):
# MyDataStream 的 __iter__() 被调用 (生成器方式)
current = self.start
for _ in range(self.count):
yield current # 每次 yield 都会暂停并返回一个值
current += 1
# 创建实例对象
stream = MyDataStream(10, 3)
# 迭代实例对象
for item in stream:
print(item)
运行结果如下。
10
11
12
分析:
虽然 MyDataStream 类没有直接实现 __next__() 方法,但其 __iter__() 方法是一个生成器函数。当 __iter__() 被调用时,它会返回一个生成器迭代器,这个生成器迭代器内部自动实现了 __next__() 和 StopIteration 逻辑。
这是 Python 中创建自定义迭代器最常用的方法,因为它极大地简化了代码。
示例 4:没有 __next__() 方法(或 __iter__())的对象
# 定义类
class MyObject:
def __init__(self, value):
self.value = value
# 创建实例
obj = MyObject(100)
try:
print(next(obj)) # 直接对非迭代器对象调用 next()
except TypeError as e:
print(e)
try:
print(iter(obj)) # 尝试获取非可迭代对象的迭代器
except TypeError as e:
print(e)
运行结果如下。
(报错)'MyObject' object is not an iterator
(报错)'MyObject' object is not iterable
分析:
如果一个对象不是迭代器(没有实现 __next__()),或者不是可迭代对象(没有实现 __iter__()),那么对它调用 next() 或尝试迭代会引发 TypeError 异常。
