关于default的引用计数如何使用PyDict_SetDefault

How to use PyDict_SetDefault with regard to the refence count of default

我想知道如何在不造成引用计数灾难的情况下使用 PyDict_SetDefault

该文档没有说明任何关于被盗参考的信息,一些测试表明它没有 "steal the reference" of default。但是当且仅当字典中不存在该键时,它才会

这对我来说似乎真的很复杂,因为它太容易出错了。我目前是这样使用它的:

item = PyDict_SetDefault(dictionary, key, defaultvalue);
if (item != defaultvalue) {
    /* key was present, the item is a borrowed reference and default is at refcount 1.*/
    Py_INCREF(item);         /* item at refcount 2 */
    Py_DECREF(defaultvalue); /* default at refcount 0 */
    defaultvalue= NULL;
} else {
    /* key wasn't present, item is default and has refcount 2. */
    defaultvalue = NULL;
}

最后,我和我自己的字典 itemdefault 的参考被彻底删除了,对吧?

有没有更好的方法来处理这种情况,而无需明确检查我是否错过了 item == default?真的那么复杂还是我错过了明显而简单的方法?

item = PyDict_SetDefault(dictionary, key, defaultvalue);
Py_INCREF(item);
Py_DECREF(defaultvalue);

是否 item==defaultvalue 并不重要——无论发生什么,你都获得了 item 的所有权(通过增加它)并释放了 defaultvalue 的所有权(通过减少它,假设你不想将它用于任何其他用途)。

如果 key 存在于字典中,则 defaultvalue 不被使用,因此它的引用计数保持为 1,并且它被 decref 销毁。 item 以 1 的引用计数返回(因为它存储在字典中)并且我们递增它,因为我们也在使用它所以 item 现在的引用计数为 2。

如果 key 不存在,则 defaultvalue 存储在字典中(现在引用计数为 2)并返回。 itemdefaultvalue 是一样的。我们递增 item (refcount 3) decref defaultvalue (refcount 2).

无论哪种方式,我们都在同一个地方结束。