2016-11-26 22 views
38

有人可以解釋以下嗎?使用id()時,[]和list()之間有區別嗎?

爲什麼id相同,但列表不同?

>>> [] is [] 
False 
>>> id([]) == id([]) 
True 

列表創建是否有區別?

>>> id(list()) == id(list()) 
False 
>>> id([]) == id([]) 
True 

這是怎麼發生的?我得到兩個不同的名單。爲什麼不只有一個或三個或更多?

>>> [].__repr__ 
<method-wrapper '__repr__' of list object at 0x7fd2be868128> 
>>> [].__repr__ 
<method-wrapper '__repr__' of list object at 0x7fd2be868170> 
>>> [].__repr__ 
<method-wrapper '__repr__' of list object at 0x7fd2be868128> 
>>> [].__repr__ 
<method-wrapper '__repr__' of list object at 0x7fd2be868170> 

回答

76

您使用id()錯了。 id([])對象的內存ID立即丟棄。畢竟,一旦id()完成它,任何東西都不再引用它。所以下一次你使用id([]) Python看到了重新使用內存的機會,而且看到這些地址確實是一樣的。

然而,這是一個實現細節,一個你不能依靠,也不會總是能夠重複使用的內存地址。

注意id()值僅用於對象的壽命獨特,請參閱documentation

這是保證是用於在其壽命期間該對象獨特和恆定的整數。 具有非重疊壽命的兩個對象可能具有相同的id()值。

(大膽強調我的)。

id(list())不能重新使用的內存位置可能是由於造成推堆棧上的當前幀調用一個函數,然後再彈出它list()調用返回時將多餘的堆上突變。

[]list()都產生一個新的空列表對象;但你需要首先創建這些單獨的列表(在這裏ab)引用:當你使用[].__repr__

>>> a, b = [], [] 
>>> a is b 
False 
>>> id(a) == id(b) 
False 
>>> a, b = list(), list() 
>>> a is b 
False 
>>> id(a) == id(b) 
False 

同樣的情況。 Python解釋有一個特殊的全局名稱,_,你可以用它來引用最後產生的結果是:

>>> [].__repr__ 
<method-wrapper '__repr__' of list object at 0x10e011608> 
>>> _ 
<method-wrapper '__repr__' of list object at 0x10e011608> 

這就產生了一個額外的參考,所以__repr__方法,並推而廣之,你創建的空列表因爲它,仍被視爲活動。內存位置未被釋放,不適用於您創建的下一個列表。

但再次執行[].__repr__,巨蟒現在結合_到該新方法的對象。突然之前的__repr__方法不再被任何東西引用,並且可以被釋放,列表對象也是如此。

你執行[].__repr__第一存儲位置的第三次又是可以重複使用,所以Python做到了這一點:

>>> [].__repr__ # create a new method 
<method-wrapper '__repr__' of list object at 0x10e00cb08> 
>>> _   # now _ points to the new method 
<method-wrapper '__repr__' of list object at 0x10e00cb08> 
>>> [].__repr__ # so the old address can be reused 
<method-wrapper '__repr__' of list object at 0x10e011608> 

你從來沒有創建兩個以上的列表;前一個(仍然參考_)和當前的一個。如果您想查看更多內存位置,請使用變量添加另一個引用。

相關問題