使用PyDict_SetItemString引用计数

时间:2016-11-20 03:02:15

标签: python python-2.7

我想知道当一个新值被设置到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的文档专门提到了列表会发生什么:This function “steals” a reference to item and discards a reference to an item already in the list at the affected position.

PyDic_SetItemPyDict_SetItemString都没有说明如何处理词典的替换。

1 个答案:

答案 0 :(得分:3)

旧值的引用计数由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

仍然非常简单,显然所有与dict中插入/替换值相关的繁重工作实际上都是由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) */

减少旧值的引用计数。