考虑以下示例:
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__
叫?如果结果被忽略,则没有理由调用它。
PEP 424中有一些指示:一种公开长度提示的方法:
CPython当前在几种类型上定义了length_hint方法,例如各种迭代器。然后,各种其他功能(例如list)将使用此方法来根据length_hint返回的估计值对列表进行大小调整。然后,没有大小且因此不应定义len的类型可以定义length_hint,以允许估计或计算大小(例如许多迭代器)。
和:
能够根据由length_hint估计的预期大小来预分配列表可能是一项重大的优化。观察到CPython比PyPy运行某些代码快,完全是因为存在这种优化。
因此似乎为了进行预分配而进行list
调用__len__
。之后,您的列表可以根据需要增加。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句