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__() 方法。
提示:
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 异常。
