0

有人可以详细解释一下:

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。因此,如果你们能告诉我幕后发生的事情,我将不胜感激。提前致谢:)

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

4

2 回答 2

2

为了避免相同文字的两次出现是否是同一个对象的问题(这是一个实现细节),让我们为我们的值命名,以便相同的名称始终引用同一个对象。

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

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

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

所以当然float(x) is float(x)True,因为这和写作一样x is x。同样对于int(y) is int(y). 文档“对于一般的 Python 对象xfloat(x)委托给x.__float__()“如果x定义__int__(),则int(x)返回x.__int__(),这是有道理的,float.__float__两者int.__int__都只返回对象本身。

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

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

但这是一个实现细节。解释器将被允许使用缓存来返回相同的float对象而不是构造多个对象,在这种int情况下,它实际上是这样做的,至少对于CPython中的小int值。

>>> x1 = int(x)
>>> x2 = int(x)
>>> x1 is x2
True
于 2021-08-31T13:33:01.333 回答
1

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

您可以在 SO 上找到其他问题,提供有关此缓存的更多详细信息,例如:解释器维护的整数缓存是什么?

于 2021-08-31T13:13:00.643 回答