2016-01-06 40 views
3

我得到如下:numpy.float64對象的id()是相同的,即使它們的值不同?

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

這很迷人。 Python 3中的同樣處理:在解釋器中鍵入'id(numpy.float64(*))',其中'*'是一串隨機數,總是打印同樣的東西。 –

+0

另請參閱:http://stackoverflow.com/q/17132047/270986 –

回答

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 
+0

好點,我同意這很可能是此行爲的原因。進一步思考,我嘗試通過關閉gc與「gc.disable()」來驗證這一點,但這仍然給出了相同的行爲,甚至「gc.set_debug(gc.DEBUG_SAVEALL)」還不足以保持第一個float64被收集。是否有其他垃圾收集器可以關閉? –

+1

其他垃圾回收器:是的。這可以關閉:不。 gc模塊控制運行在基於常規引用計數的gc之上的循環垃圾收集器;沒有辦法關閉基於基準引用計數的gc。 –

4

試想一下,你把書架上的一本書,然後有人注意到你不使用它,把書從書架上拿下來釋放一些空間。然後,您可以在便利的位置放置另一本書。

如果你突然意識到你在同一地點有兩本不同的書,你認爲現實中存在一個錯誤嗎? ;-)

numpy.float64(100)上調用id之後,您無法引用您所創建的float對象,因此解釋器完全可以自由地重用該id。

2

根據該Docs,所述id()函數這樣

ID(對象)

返回的對象的「同一性」來描述。這是一個整數(或長整數 ),它在其生命週期中保證對此 唯一且恆定。 具有非重疊使用期限的兩個對象 可能具有相同的id()值。

因此,可能發生,但不一定總是。因爲它們不能同時存在,所以它們最終會捕獲相同的id

然而,在這種情況下

a = numpy.float64(10) 
b = numpy.float64(100) 
print a==b, id(a)==id(b) 

他們同時存在,所以他們不能具有相同的id

相關問題