我得到以下内容:
import numpy
print id(numpy.float64(100)) == id(numpy.float64(10))
print numpy.float64(100) == numpy.float64(10)
给出:
True
False
请注意,如果我创建两个float64对象然后比较它们,那么它似乎按预期工作:
a = numpy.float64(10)
b = numpy.float64(100)
print a==b, id(a)==id(b)
给出:
False
False
基于https://docs.python.org/2/reference/datamodel.html,如果它们的值不同,两个对象的id是否总是不同?如果值不同,我怎样才能获得匹配的id?
这是numpy中的某种错误吗?
答案 0 :(得分:4)
这看起来像是内存重用的怪癖,而不是NumPy错误。
该行
id(numpy.float64(100)) == id(numpy.float64(10))
首先创建一个浮点numpy.float64(100)
,然后在其上调用id
函数。然后Python的垃圾收集器立即释放这个内存,因为没有更多的引用它。内存插槽可以由任何创建的新对象自由重用。
创建numpy.float64(10)
时,它占用相同的内存位置,因此id
返回的内存地址相等。
当您查看字节码时,这一系列事件可能更清晰:
>>> dis.dis('id(numpy.float64(100)) == id(numpy.float64(10))')
0 LOAD_NAME 0 (id)
3 LOAD_NAME 1 (numpy)
6 LOAD_ATTR 2 (float64)
9 LOAD_CONST 0 (100)
12 CALL_FUNCTION 1 (1 positional, 0 keyword pair) # call numpy.float64(100)
15 CALL_FUNCTION 1 (1 positional, 0 keyword pair) # get id of object
# gc runs and frees memory occupied by numpy.float64(100)
18 LOAD_NAME 0 (id)
21 LOAD_NAME 1 (numpy)
24 LOAD_ATTR 2 (float64)
27 LOAD_CONST 1 (10)
30 CALL_FUNCTION 1 (1 positional, 0 keyword pair) # call numpy.float64(10)
33 CALL_FUNCTION 1 (1 positional, 0 keyword pair) # get id of object
36 COMPARE_OP 2 (==) # compare the two ids
39 RETURN_VALUE
答案 1 :(得分:4)
想象一下,你把一本书放在架子上,然后有人注意到你没有使用它,并将书从架子上取下以释放一些空间。然后,您可以在方便的位置将另一本书放在书架上。
如果你突然意识到你在同一个地方有两本不同的书,你认为现实中有一个错误吗? ; - )
在id
上调用numpy.float64(100)
后,您无法引用您创建的浮动对象,因此解释器可以完全自由地重用该ID。
答案 2 :(得分:3)
根据Docs,id()
函数就像这样描述
ID(对象)
返回对象的“标识”。这是一个整数(或 长整数)保证唯一且常量 对象在其生命周期中。 两个生命周期不重叠的对象 可能具有相同的id()值。
所以这可能发生,但不一定总是如此。由于它们不是同时存在,它们最终会捕获相同的id
。
然而,在这种情况下
a = numpy.float64(10)
b = numpy.float64(100)
print a==b, id(a)==id(b)
他们做同时存在,因此不能具有相同的id
。