2015-09-24 53 views
6

我知道python內置函數id()返回一個在對象生命週期中唯一的ID。我知道,具有非重疊生命期的對象最終可能會有相同的ID。不過,我想明白這一點,而混亂的行爲:Python對象上的可重複的ID衝突

>>> id(matplotlib.image.BboxImage.set_cmap) 
4424372944 
>>> id(numpy.ma.core.MaskedArray.sum) 
4424372944 

而且在跨多個翻譯實例事實上,行爲是重複的:

Mac:~$ python2.7 -c "import matplotlib.image; import numpy; print id(matplotlib.image.BboxImage.set_cmap), id(numpy.ma.core.MaskedArray.sum)" 
4343186208 4343186208 
Mac:~$ python2.7 -c "import matplotlib.image; import numpy; print id(matplotlib.image.BboxImage.set_cmap), id(numpy.ma.core.MaskedArray.sum)" 
4521153312 4521153312 
Mac:~$ python2.7 -c "import matplotlib.image; import numpy; print id(matplotlib.image.BboxImage.set_cmap), id(numpy.ma.core.MaskedArray.sum)" 
4358591264 4358591264 
Mac:~$ python2.7 -c "import matplotlib.image; import numpy; print id(matplotlib.image.BboxImage.set_cmap), id(numpy.ma.core.MaskedArray.sum)" 
4389970720 4389970720 

看來,matplotlib.image.BboxImage.set_cmapnumpy.ma.core.MaskedArray.sum總是得到相同的ID甚至在Python解釋器的不同場合下也是如此。

現在我明白這與id()的文檔一致,因爲這兩個對象是在訪問時動態創建的,所以確實會有非重疊的生命週期。但爲什麼這兩個不相關的對象總是用相同的ID結束呢?

(這個問題是Object methods of same class have same id?不同,因爲在這裏,我問爲什麼,這是跨越多個解釋實例重複,而不是簡單地與非重疊壽命對象的僞ID衝突。)

回答

6

這會成真任何實例方法,它是您正在測試的兩個對象的類型。每次訪問描述符時,都會實例化一個新的instancemethod對象。由於您沒有保存對新創建方法的引用,只要id返回,它就有資格進行垃圾回收,並且顯然在下次調用id之前收集垃圾回收,因此可以重新使用相同的內存位置。

這種行爲可以看出,在另一種方式:

>>> x = matplotlib.image.BboxImage.set_cmap 
>>> y = matplotlib.image.BboxImage.set_cmap 
>>> id(x) == id(y) 
False 

xy是兩個不同的對象的引用,因爲引用set_cmap創建每次新instancemethod對象。