Python __next__() 方法

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 异常。

上一篇: __iter__()

下一篇: __contains__()

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号