【问题标题】:Does float create different object instances each time we call them?每次我们调用它们时,float 会创建不同的对象实例吗?
【发布时间】:2021-08-31 13:06:03
【问题描述】:

能否详细解释一下:

print(float(5.3) is float(5.3))#True
print(float(5) is float(5))#False
print(int(5) is int(5))#True

第一个返回 False,第二个返回 True。因此,如果你们能告诉我幕后发生的事情,我将不胜感激。 提前致谢:)

编辑:感谢每个人的 cmets,但我真的明白 ID 在第二种情况下是不同的,在第一种情况下是相同的。显然,可以使用 id() 找到它。 但我真正想知道的是为什么 ID 不同?

【问题讨论】:

  • 我想一种更正确的检查对象是否相等的方法:print(id(float(5)) == id(float(5))),它给出了True
  • id(x) == id(y) 应始终等同于 x is y。但是,结果可能会因 Python 的不同版本或实现而异。
  • 你不是在测试你认为你在这里的东西。同一行的两个字面量不会同时存在(只要调用float()int(),它们就有资格进行垃圾回收),因此您无法区分“对同一对象的两个引用”和“碰巧分配在同一内存地址的两个单独创建的对象”。
  • 是的,很好。
  • @jasonharper 谢谢你,先生。你的回答看起来很有说服力。如果您不介意,如果您能详细地向我解释一下,我将不胜感激:)。就像您在这种情况下所说的垃圾收集一样。谢谢

标签: python


【解决方案1】:

为了避免两次出现的同一个字面量是否是同一个对象(即an implementation detail)的问题,让我们为我们的值命名,以便同一个名称始终指代同一个对象。

>>> x = 5.3
>>> y = 5

我们可以看到,实际上,当您分别对已经是浮点数或整数的值调用floatint 构造函数时,它们不会构造新对象,而是返回原始对象:

>>> x is float(x)
True
>>> y is int(y)
True

所以float(x) is float(x) 当然是True,因为这与写x is x 相同。 int(y) is int(y) 也是如此。 The docs say "对于一般的 Python 对象 xfloat(x) 委托给 x.__float__()""如果 x 定义 __int__()int(x) 返回 @987654339 @",而且float.__float__int.__int__ 都只返回对象本身是有道理的。

但是,当您在同一个 int 值上多次调用 float 构造函数时,您每次都在构造一个新对象:

>>> y1 = float(y)
>>> y2 = float(y)
>>> y1 is y2
False

但这是一个实现细节。解释器将被允许使用缓存返回相同的float 对象而不是构造多个对象,在int 的情况下,这就是它实际上所做的,至少for small int values in CPython

>>> x1 = int(x)
>>> x2 = int(x)
>>> x1 is x2
True

【讨论】:

  • 非常感谢!!!我对您的回答有了一些很好的理解:)如果您有空的话,如果您能解释一下您所写的最后几行的详细信息,我将不胜感激。关于那个缓存。
  • 如果你点击the other Q&A的链接,你可以找到关于int对象如何在CPython中缓存的解释。
  • 哦,好吧。谢谢:)
【解决方案2】:

Python 缓存小整数对象,您的示例表明,当这种情况发生时并不总是显而易见的。因此,您应该通过id() 来比较身份。

您可以在 SO 上找到其他问题,以提供有关此缓存的更多详细信息,例如:What's with the integer cache maintained by the interpreter?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    • 2021-06-07
    • 2012-02-18
    • 2019-07-28
    • 2011-09-12
    相关资源
    最近更新 更多