+-

我想知道当在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) */
这减少了旧值的引用计数.
点击查看更多相关文章
转载注明原文:使用PyDict_SetItemString进行引用计数 - 乐贴网