理解 CPython 中相同的物件 ID
在 CPython 中,內建函數 id() 傳回表示物件記憶體位址的唯一整數。有趣的是,在某些情況下,兩個不同的物件可以具有相同的ID,如下例所示:
<code class="python">tuple1 = () tuple2 = () dict1 = {} dict2 = {} list1 = [] list2 = [] # Tuples are immutable assert(id(tuple1) == id(tuple2)) # Dicts are mutable assert(id(dict1) != id(dict2)) # Lists are mutable too assert(id(list1) != id(list2)) # Unexpectedly, empty dicts and lists have the same ID assert(id({}) == id({})) assert(id([]) == id([]))</code>
行為背後的原因
這種奇特的現象這種現象的發生是由於CPython 記憶體分配器的運行時行為及其處理對象創建和銷毀的方式造成的。當呼叫 id({}) 時,CPython 會建立一個新的字典物件並將其指派到記憶體中的暫存位置。然而,這個臨時物件在 id() 函數返回其 ID 後立即被銷毀。當呼叫下一個 id({}) 時,新字典可能恰好在與前一個字典相同的記憶體位置中創建,從而導致即使這些物件不同,也會產生相同的 ID。
這個推理是以下序列中觀察到的行為進一步支持了這一點:
<code class="python">id([]) 4330909912 x = [] id(x) 4330909912 id([]) 4334243440</code>
可變性和緩存的影響
值得注意的是,可變性在此行為中扮演間接角色。雖然可變物件(例如列表和字典)不符合代碼物件快取的條件,但不可變物件(例如空元組和某些字串)可以。這意味著在同一個程式碼物件中,這些不可變物件將被重複使用,可能導致將相同的 ID 指派給不同的不可變物件。
Id 唯一性和物件生命週期
總之,物件的 ID 僅在其生命週期內是唯一的。一旦一個物件被銷毀或在創建之前,另一個物件可能會被指派相同的 ID。這種行為強調了 CPython 中物件 ID 的短暫性,以及在底層 Python 實現的上下文中理解記憶體分配和物件創建動態的重要性。
以上是為什麼 CPython 中兩個不同的物件可以具有相同的 ID,即使它們不是同一個物件?的詳細內容。更多資訊請關注PHP中文網其他相關文章!