微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么在使用__getitem__进行迭代时调用__len__而不使用结果?

如何解决为什么在使用__getitem__进行迭代时调用__len__而不使用结果?

PEP 424中有一些指示:一种公开长度提示的方法

cpython当前在几种类型上定义了 方法,例如各种迭代器。然后,各种其他功能(例如list)将使用此方法来根据 返回的估计值对列表进行 。然后,没有大小且因此不应定义 可以定义 ,以允许估计或计算大小(例如许多迭代器)。

和:

能够根据由 估计的预期大小来预分配列表可能是一项重大的优化。观察到cpython比PyPy运行某些代码快,完全是因为存在这种优化。

因此,似乎要进行list调用__len__才能预先分配列表。之后,您的列表可以根据需要增加

解决方法

考虑以下示例:

import random


class Class1:
    def __getitem__(self,item):
        print('getitem',item)
        result = random.randint(0,10)
        if not result:
            raise IndexError
        return result


class Class2(Class1):
    def __len__(self):
        print('len',3)
        return 3


print(list(Class1()))
print(list(Class2()))

输出:

getitem 0
getitem 1
[10]
len 3
getitem 0
getitem 1
getitem 2
getitem 3
getitem 4
[8,10,2,10]

因此,进行遍历时Class1()没有,__len__但是代码可以正常工作。当有__len__Class2()它被称为但是结果3完全不使用迭代获得3项后继续。我的问题是:为什么__len__叫?如果结果被忽略,则没有理由调用它。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。