请参阅PEP 424的“基本原理”部分,该部分介绍__length_hint__
并提供了有关动机的见解:
能够根据预期大小(由估算)预先分配列表__length_hint__
可能是一项重大优化。观察到cpython比PyPy运行某些代码快,完全是因为存在这种优化。
除此之外,用于的文档还object.__length_hint__
验证了这纯粹是一项优化功能:
叫执行operator.length_hint()
。应该返回对象的估计长度(可以大于或小于实际长度)。长度必须是整数>= 0
。 此方法 ,对于正确性从来不需要。
__length_hint__
之所以如此,是因为它可以带来一些不错的优化。
PyObject_LengthHint
,首先尝试从中获取值object.__len__
(如果已定义),然后尝试查看是否object.__length_hint__
可用。如果两者都不存在,则返回8
for列表的默认值。
listextend``list_init
如Eli在其答案中所述被调用,根据此PEP进行了修改,以为定义a__len__
或a的任何内容提供此优化__length_hint__
。
list
不是唯一受益于此的bytes
对象,对象当然可以这样做:
>>> bytes(Foo())
len
getitem 0
...
b'\x00\x01\x04\t\x10\x19'
对象也是如此,bytearray
但只有当您使用extend
它们时:
>>> bytearray().extend(Foo())
len
getitem 0
...
和tuple
创建中间序列以填充自身的对象:
>>> tuple(Foo())
len
getitem 0
...
(0, 1, 4, 9, 16, 25)
如果有人在徘徊,为什么在上课 之前 而不是在上课之后'iter'
打印确切的内容: __'len'``Bar``Foo
这是因为如果手中的对象定义了__iter__
Python, 则将首先调用它 来获取迭代器,从而也运行它print('iter')
。如果回到使用,则不会发生相同的情况__getitem__
。