You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python:自定义序列迭代时__len__()方法为何被忽略?

问题原因与解决方案

这个问题我之前也碰到过,核心原因是Python处理实现了__getitem__但未实现__iter__的对象时,并不会用__len__来终止迭代。

它的迭代逻辑是这样的:从索引0开始,依次调用__getitem__(0)、__getitem__(1)……直到某次调用抛出IndexError,才会停止循环。你的__getitem__方法没有做索引越界检查,不管传入多大的idx都直接返回idx,所以循环会无限进行下去,完全不会理会__len__返回的数值。

解决方案一:给__getitem__添加越界检查

只需要在__getitem__里判断索引是否超出范围,超出时抛出IndexError即可:

class Test():
    def __init__(self):
        pass
    def __len__(self):
        return 5
    def __getitem__(self, idx):
        # 检查索引是否超过序列长度
        if idx >= len(self):
            raise IndexError
        return idx
t = Test()
for i, x in enumerate(t):
    print(i, x)

这样当迭代到idx=5时,会触发IndexError,循环就会终止,输出正好是你预期的0 0到4 4。

解决方案二:实现标准迭代器接口

如果你想更贴合Python的迭代器规范,可以实现__iter__和__next__方法,主动控制迭代的终止:

class Test():
    def __init__(self):
        self._current_idx = 0
    def __len__(self):
        return 5
    def __iter__(self):
        # 返回迭代器本身
        return self
    def __next__(self):
        if self._current_idx >= len(self):
            # 终止迭代的标准异常
            raise StopIteration
        current_val = self._current_idx
        self._current_idx += 1
        return current_val
t = Test()
for i, x in enumerate(t):
    print(i, x)

这种方式更清晰,也符合Python迭代器的设计思路,__len__依然可以正常使用,同时迭代会在达到长度后自动停止。

补充一句:__len__方法的作用是提供序列的长度信息(比如让len(t)生效),但它本身并不会直接参与迭代的终止逻辑,除非你在迭代相关的方法里主动调用它来做判断。

内容的提问来源于stack exchange,提问作者teubi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:59:50