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

为何Python的list()会调用对象的__len__()方法?

为何Python的list()会调用对象的__len__()方法?

这个问题问得好!我当初刚接触Python的魔法方法时也懵过,咱们一步步拆解来看。

首先得说清楚为什么list()会触发__len__调用:
这完全是Python为了性能优化做的手脚。你想啊,当你用list()把一个可迭代对象转成列表时,如果这个对象不仅能被迭代(实现了__iter__),还能返回自己的长度(实现了__len__),那Python就可以先调用__len__知道元素总数,然后一次性分配刚好能装下所有元素的内存空间——要是不这么做,list只能从默认大小开始,迭代一个元素就append一个,空间不够了再扩容,每次扩容都要重新分配内存、复制现有元素,效率低多了。预分配空间能省掉这些额外开销,这是个很实用的优化。

结合你的代码例子来看:
你的MyContainer类既实现了__iter__(满足可迭代的要求),又实现了__len__,所以list()处理它的时候,就会先调用__len__拿到3,初始化一个长度为3的空列表,再调用__iter__获取迭代器把元素填进去,所以你才会看到__iter__和__len__都被调用了。而你之前用已经生成的迭代器i转列表时,迭代器本身是没有__len__方法的(你可以试试len(i),肯定会报错),list()没法预分配空间,只能边迭代边扩容,自然不会触发__len__调用。

再说说文档在哪里:
这个行为在Python官方文档里是有明确说明的:

  • 在list()构造函数的说明中,提到当传入的可迭代对象实现了__len__时,会利用该方法来优化内存分配;
  • 另外在Python数据模型文档里,关于__len__方法的描述也提到,容器类型实现__len__是为了让内置函数和操作符能利用它来提升性能,list()就是其中一个典型场景。

备注:内容来源于stack exchange,提问作者odigity

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 14:03:04