Python __iter__() 方法

Python __iter__() 语法

__iter__() 是 Python 的一个特殊方法(又称 “魔法方法” 或 “双下划线方法”),它用于定义当对象被迭代(比如使用 iter() 函数或 for 循环)时,如何返回一个迭代器对象。

__iter__() 的主要作用是返回一个迭代器对象,从而使得自定义对象能够成为可迭代对象(iterable)。

语法:

class MyIterable:
    def __iter__(self):
        # 返回一个迭代器对象,通常是 self 或者一个实现了 __next__() 方法的新对象
        return MyIterator(self._data) # 假设 MyIterator 是一个独立的迭代器类

        # 或者对于简单情况,可以直接返回 self,如果 MyIterable 也实现了 __next__()
        # return self

说明:

__iter__() 方法不接收任何参数,除了 self(实例本身)。

__iter__() 方法必须返回一个迭代器对象,该迭代器对象必须实现 __next__() 方法。

提示:

  • 如果一个类实现了 __iter__() 方法,那么它的实例就是 “可迭代对象(iterable)” 。可迭代对象可以使用 for…in 循环、list()tuple()sum() 等对其进行操作。
  • 如果一个类同时实现了 __iter__() 和 __next__() 这两个方法,那么它的实例就是 “迭代器对象(Iterator)”。迭代器对象本质上也是一个可迭代对象。

Python __iter__() 摘要

属于 Python 魔法方法
使用频率
官方文档 查看
相关方法 __next__()

Python __iter__() 示例

接下来,我们通过几个简单的例子来讲解一下 Python __iter__() 方法是如何使用的。

示例 1:对内置可迭代对象使用 __iter__()

nums = [10, 20, 30]

# 获取列表的迭代器
iterator = nums.__iter__()
print(type(iterator))

# 使用 next() 函数从迭代器获取元素
print(next(iterator))
print(next(iterator))

# 再次尝试获取,会抛出 StopIteration 异常
try:
    print(next(iterator))
    print(next(iterator))   # 预期会报错
except StopIteration:
    print('已达到迭代器末尾')

运行结果如下。

<class 'list_iterator'>
10
20
30
已达到迭代器末尾

分析:

内置的可迭代对象(如列表、字符串、元组)内部都实现了 __iter__() 方法。在这个例子中,当我们调用 nums.__iter__() 或 iter(nums) 时,会得到一个相应的迭代器对象,这个迭代器对象实现了 __next__() 方法,可以逐个获取元素。

示例 2:自定义可迭代对象

class MyCollection:
    def __init__(self, data):
        self._data = list(data)

    def __iter__(self):
        # MyCollection 的 __iter__() 被调用,返回新的迭代器
        return MyCollectionIterator(self._data)

class MyCollectionIterator:
    def __init__(self, data):
        self._data = data
        self._index = 0

    def __next__(self):
        # 实现迭代器的核心逻辑
        if self._index < len(self._data):
            item = self._data[self._index]
            self._index += 1
            return item
        else:
            raise StopIteration

# 创建可迭代对象
items = MyCollection(['apple', 'banana', 'cherry'])

# 使用 for 循环迭代 (触发 __iter__())
for item in items:
    print(item)

# 再次迭代 (触发 __iter__(),返回新的迭代器)
for item in items:
    print(item)

# 将可迭代对象转换为列表 (触发 __iter__())
print(list(items))

运行结果如下。

apple
banana
cherry

apple
banana
cherry
['apple', 'banana', 'cherry']

分析:

如果想要创建自定义可迭代对象,小伙伴们可以参考这个例子,这是比较标准的做法。

在 MyCollection 类中,我们自定义实现 __iter__() 方法,用于返回一个独立的 MyCollectionIterator 实例。并且 MyCollectionIterator 类也实现了 __next__() 方法,负责实际的迭代逻辑。每次对 items 进行迭代时,__iter__() 都会返回一个新的迭代器,确保可以进行多次独立的迭代。

示例 3:自定义可迭代对象也是迭代器(__iter__ 返回 self)

class MyOneTimeIterator:
    def __init__(self, start, end):
        self.current = start
        self.end = end

    def __iter__(self):
        # __iter__() 被调用,返回自身作为迭代器
        return self

    def __next__(self):
        # 实现迭代逻辑
        if self.current < self.end:
            value = self.current
            self.current += 1
            return value
        else:
            # 迭代结束,抛出 StopIteration 异常
            raise StopIteration

# 创建一个一次性迭代器
iterator = MyOneTimeIterator(1, 4)

# 第一次迭代
for i in iterator:
    print(i)

# 尝试第二次迭代 (会失败,因为迭代器已耗尽)
for i in iterator:
    print(i)

运行结果如下。

1
2
3

分析:

当 __iter__() 返回 self 时,意味着对象本身就是一个迭代器。这种模式通常用于一次性迭代的场景,因为迭代器状态(如 self.current)会在迭代过程中被改变。

第二次尝试迭代 one_time_iter 时,由于 self.current 已经达到了 self.end,__next__ 会立即抛出 StopIteration 异常,导致 for 循环不执行任何操作。

示例 4:__iter__() 的缺失

class MyIterable:
    def __init__(self, data):
        self.data = data

# 创建实例
obj = MyIterable([1, 2, 3])

# 尝试迭代 MyIterable
try:
    for item in obj:
        print(item)
except TypeError as e:
    print(e)

# 尝试将 MyIterable 转换为列表
try: 
    list(obj)
except TypeError as e:
    print(e)

运行结果如下。

(报错)'MyIterable' object is not iterable
(报错)'MyIterable' object is not iterable

分析:

如果一个类没有实现 __iter__() 方法,也没有实现 __getitem__() 来作为回退,我们还尝试对其进行迭代,此时 Python 就会抛出 TypeError 异常。

上一篇: __delitem__()

下一篇: __next__()

给站长反馈

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

邮箱:lvyenet@vip.qq.com

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