簡體   English   中英

關於 python 中的字典分配問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM