[英]Question about dictionary assignment in python
我想知道為什么這段代碼會打印出 True:
rec = {"Name" : "Python", "Age":"20", "Addr" : "NJ", "Country" : "USA"}
id1 = id(rec)
del rec
rec = {"Name" : "Python", "Age":"20", "Addr" : "NJ", "Country" : "USA"}
id2 = id(rec)
print(id1 == id2)
好吧,據我所知,如果我們要更改 id1 中的某些內容,那么 rec 也會更改。 那么為什么該代碼不刪除 id1,因為 rec 被刪除了?
如果您想要一個非常技術性的答案,特定於CPython ,參考 Python 實現(我假設這里包括大多數人,默認情況下他們說“Python”時的意思): ZA7F5F35426B9274173ZZA7F5F35426B9274173Z923 中的許多常見 object 類型是從稱為“a63821FC923”的東西分配的空閑列表”,它是一個數組,或者在某些情況下我認為是一個鏈表,其中包含已分配 memory 的相同類型的對象。 這意味着,例如,可以通過反復為單個字典重用相同的 memory 分配而不是反復 malloc/釋放它們來快速創建和銷毀許多短期字典。
例如對於dict
對象,freelist 可以在這里看到: https://github.com/python/cpython/blob/61289d436661025a3111065482275d49a4850b8d/Objects/dictobject.c#L252
(還有一個單獨的字典鍵,我現在將忽略它。)
當一個新的dict
被創建時, new_dict
function 首先檢查free_list
中是否有空槽,如果有則重用它(稍微偽代碼重新解釋):
PyDictObject *mp;
if (numfree) {
mp = free_list[--numfree];
_Py_NewReference((PyObject *)mp);
}
else {
// Allocate a new PyDictObject
// Note, we do NOT put this on the freelist yet since it's still in use;
// we'll do that later
mp = PyObject_GC_New(PyDictObject, &PyDict_Type);
}
稍后,在dict_dealloc
中,當對 object 剩余的引用為零時調用,如果free_list
上有空間,我們將 object 保留在那里而不是釋放它的 ZCD69B4957F06CD818D7BF3D61980E2:
if (numfree < PyDict_MAXFREELIST && Py_TYPE(mp) == &PyDict_Type)
free_list[numfree++] = mp;
else
Py_TYPE(mp)->tp_free((PyObject *)mp);
為了清楚起見,請注意存儲在free_list
中的PyDictObject
並不一定意味着它們的任何鍵或值也保存在 memory 中。 這僅適用於PyDictObject
本身,它包含指向鍵/值的 arrays 的指針以及一些額外的內部簿記。
如果碰巧您的初始del rec
釋放了free_list
中的一個插槽,那么立即創建一個新的 dict (無論其內容如何)將使用相同的插槽,因此具有相同的id()
,因為在 CPython 中id()
只是返回object 的 memory 地址。 當然,即使沒有空閑列表,這也很容易偶然發生。
id1 是一個自變量。 它已從記錄中分配了一個值。 現在,如果刪除了 rec,id1 會在其中存儲一個單獨的值,該值不在該字典 rec 中。 這就是為什么它沒有被刪除
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.