class cls: def __init__(self,data): self.data = data def __iter__(self,index): print("call item") return self.data[index] def __getitem__(self,index): print("call getitem") return self.data[index] obj = cls([3,2,9,11]) for i in obj: print(i)
你写的 __iter__ 方法签名不对,导致 for 循环调用时传参不匹配,才会报错。 在 Python 中,迭代协议要求: __iter__(self) —— 无额外参数,返回一个迭代器(即实现了 __next__ 的对象)。 如果只想让实例支持“下标遍历”,可以只保留 __getitem__,Python 会自动从 0 开始依次调用它,直到抛出 IndexError。 你既写了 __iter__ 又写了 __getitem__,但 __iter__ 的签名写成了 __iter__(self, index),于是 for 循环在调用 iter(obj) 时只传了 1 个实参(self),就会提示缺 index。 改法有两种,按需求选: 想保留“迭代器”方式(for x in obj 正常用) Python 复制 class cls: def __init__(self, data): self.data = data def __iter__(self): # 去掉 index 参数 print('call iter') return iter(self.data) # 直接让内置 list 的迭代器干活 # 或者自己写生成器: # for val in self.data: # yield val obj = cls([3, 2, 9, 11]) for i in obj: print(i) 输出 复制 call iter 3 2 9 11 只想用“下标”方式遍历,根本不用 __iter__ Python 复制 class cls: def __init__(self, data): self.data = data # 把 __iter__ 删掉,只保留 __getitem__ def __getitem__(self, index): print('call getitem') return self.data[index] obj = cls([3, 2, 9, 11]) for i in obj: # Python 会自动按 index=0,1,2… 调用 __getitem__ print(i) 输出 复制 call getitem 3 call getitem 2 call getitem 9 call getitem 11 总结 __iter__ 必须只有 self 一个参数,且要返回一个迭代器。 如果只想“像序列一样被遍历”,只写 __getitem__ 就够了,Python 会自动兜底。