只实现 `__getitem__()` 方法的对象也可以被称为“可迭代对象”吗?
只实现 __getitem__() 方法的对象实际上是可迭代对象。
但这类对象不会被 isinstance(obj, Iterable) 判定为 True(因为 Iterable 抽象基类的判定依赖 iter 方法)。
这是“实际可迭代”与“形式上被识别为 Iterable”的区别。
在 Python 中,可迭代对象的判定标准并非仅依赖 __iter__() 方法,还包括对 __getitem__() 方法的支持——只要一个对象实现了 __getitem__() 且满足以下条件,就会被视为可迭代对象:
__getitem__()接收从0开始的整数索引作为参数;- 当索引超出范围时,抛出
IndexError异常。
原理:Python 对 __getitem__ 的迭代支持
Python 的迭代机制(如 for 循环)会优先检查对象是否有 __iter__() 方法:
- 如果有,就通过
__iter__()获取迭代器进行迭代; - 如果没有,会检查是否有
__getitem__()方法。若有,且满足上述索引规范,Python 会自动生成一个“临时迭代器”,通过索引从0开始逐个访问元素,直到抛出IndexError时停止迭代。
示例:仅用 __getitem__ 实现可迭代对象
class MyIterable:
def __init__(self, data):
self.data = data
# 仅实现 __getitem__,不实现 __iter__
def __getitem__(self, index):
if index < 0 or index >= len(self.data):
raise IndexError # 超出范围抛异常
return self.data[index]
# 实例化对象
obj = MyIterable(["a", "b", "c"])
# 可被 for 循环遍历(证明是可迭代对象)
for item in obj:
print(item) # 输出:a、b、c
# 用 isinstance 验证(需注意:仅 __getitem__ 不会被 isinstance(..., Iterable) 识别为 True,但实际可迭代)
from collections.abc import Iterable
print(isinstance(obj, Iterable)) # False(因未实现 __iter__),但不影响迭代功能
注意点
- 虽然仅
__getitem__可实现迭代,但这类对象不会被isinstance(obj, Iterable)判定为True(因为Iterable抽象基类的判定依赖__iter__方法)。这是“实际可迭代”与“形式上被识别为 Iterable”的区别。 - 若
__getitem__不按“从 0 开始的整数索引”实现(如支持字符串索引),则无法被迭代。
综上:仅实现 __getitem__() 且符合索引规范的对象,是实际可迭代的,属于可迭代对象,只是在形式上可能不被 Iterable 抽象基类识别。

浙公网安备 33010602011771号