我想知道当将新值设置到 PyDict(在 C 扩展内)内的现有字段中时,内存管理/引用计数如何工作。
例如,假设按以下方式创建和填充字典:
myPyDict = PyDict_New();
tempPyObj = PyString_FromString("Original Value");
PyDict_SetItemString(myPyDict,"fieldname",tempPyObj);
Py_DECREF(tempPyObj);
从内存和引用计数的角度来看,当有后续时会发生什么
tempPyObj = PyString_FromString("New Value");
PyDict_SetItemString(myPyDict,"fieldname",tempPyObj);
Py_DECREF(tempPyObj);
原值的引用计数是否自动递减(并且内存自动释放)?
PyList_SetItem
的文档特别提到了列表会发生什么:此函数“窃取”对项目的引用,并丢弃对列表中受影响位置已存在的项目的引用。
但是 PyDic_SetItem
和 PyDict_SetItemString
都没有说明如何处理字典的替换。
最佳答案
旧值的引用计数通过 PyList_SetItem
函数的逻辑自动递减。
您不应该自己减少旧值。
如果您想了解详细信息,请查看 CPython 源代码,特别是 Objects/dictobject.c
文件。
1) PyDict_SetItemString()
https://github.com/python/cpython/blob/c8e7c5a/Objects/dictobject.c#L3250-L3262
它是 PyDict_SetItem()
的薄包装
2) PyDict_SetItem()
https://github.com/python/cpython/blob/c8e7c5a/Objects/dictobject.c#L1537-L1565
仍然非常简单,而且很明显,与在字典中插入/替换值相关的所有繁重工作实际上都是由 insertdict()
完成的。
3) insertdict()
https://github.com/python/cpython/blob/c8e7c5a/Objects/dictobject.c#L1097-L1186
是给我们答案的函数。在此函数中,您可以找到关键代码,尤其是调用:
Py_XDECREF(old_value); /* which **CAN** re-enter (see issue #22653) */
这会减少旧值的引用计数。
关于python - 使用 PyDict_SetItemString 进行引用计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40700251/