当前位置: 首页 > 面试题库 >

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

白宏大
2023-03-14
问题内容

这个问题已经在这里有了答案

为什么列表询问__len__?
(3个答案)

去年关闭。

考虑以下示例:

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__才能预先分配列表。之后,您的列表可以根据需要增加。



 类似资料:
  • 问题内容: 我一直在使用“ if”来测试自己的版本,并且一切似乎都正常。当然,如果使用signalAll()而不是signal(),这将导致严重崩溃,但是如果一次仅通知一个线程,这怎么会出错? 他们的代码在这里 -检查put()和take()方法;在Condition的JavaDoc顶部可以看到一个更简单,更重点的实现。 下面是我实施的相关部分。 PS我知道,通常,尤其是在这样的lib类中,应该让

  • 下面的程序迭代一个字符串。迭代器将其在空格之间剪切,并返回每个单词。我使用for each循环来使用iterable字符串,在该循环中,我使用与外部循环中相同的迭代器对同一字符串再次迭代。输出是:hello 0 hello 2等。。。 但它应该是:你好0你好2。。。因为外部循环已经增加了迭代器的计数器。所以我想我在这张图片中遗漏了一些关于迭代器工作的东西。。。感谢您的帮助! 代码:

  • 我使用的是JDK-8(x64)。对于<code>数组。sort</code>(原语)我在Java文档中找到了以下内容: 排序算法是弗拉基米尔·雅罗斯拉夫斯基、乔恩·本特利和约书亚·布洛赫的双轴快速排序。' 对于<code>集合。sort(对象)我找到了这个“Timsort”: 这个实现是一个稳定的、自适应的、迭代的合并…这个实现将指定的列表转储到一个数组中,对数组进行排序,并迭代列表,从数组中的相

  • 问题内容: 对于许多人来说,这可能是一个简单的问题,但令我感到困惑。我从Kathy Sierra挑选了一个示例,该示例显示了抽象类的效用,但我无法理解抽象类的总体重要性。 示例 我们有一个带有抽象方法- &的抽象类。这些方法在 BMW , Volkswagen 和 Audi的 子类中实现。 我的问题是- 为什么我们首先需要有抽象类来为每种汽车类型自定义方法?为什么在宝马的任何一种子类型中都没有这两

  • 问题内容: 这个来自json.Unmarshal docs的示例(为便于使用而不是进行了稍微修改)有效,没有错误: 工作示例的游乐场链接 但是这个经过稍微修改的示例却没有: 非工作示例的游乐场链接 它显示了这个实际上并没有帮助的模糊错误(看起来更像是一个函数调用,而不是错误的IMO): json:Unmarshal(nil * main.Animal) 这似乎是因为它是未初始化的指针。但是文档说(

  • 问题内容: 为什么这样 代替这个 问题答案: 因为如果抛出异常,则 除非 捕获到异常, 否则 在执行 该块之后没有任何代码。一个块总是执行,不管你里面发生了什么块。 __