python - 如何使用 Py Dict SetDefault 来获取默认值的引用计数

标签 python dictionary python-c-api

我想知道如何使用 PyDict_SetDefault不会造成引用计数灾难。

文档没有提及任何有关被盗引用的内容,并且一些测试表明它不会“窃取默认引用”。但当且仅当字典中不存在该键时,它才会递增它。

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

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<的所有权 (通过 decrefing 它,假设您不想将其用于其他用途)。

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

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

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

关于python - 如何使用 Py Dict SetDefault 来获取默认值的引用计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41626220/

相关文章:

python - 如何查看 Django 模型在 admin 中有多少个关系?

python - 如何解压 pkl 文件?

python - 程序第二次运行时 multiarray.pyd 出现未处理的异常

c++ - 'PyCObject_Import ("cairo", "CAPI")' C++ call yields segfault, ' import cairo' 在 python 上有效

python - Spark : Generate Map Word to List of Similar Words - Need Better Performance

python - 如何返回类实例的副本?

java - 使用 Scala-2.13 将 Java 映射转换为 Java 代码中的 Scala 不可变映射

python - 如何将嵌套字典的所有值转换为字符串?

java - 索引列表时的最佳 HashMap 初始容量

python - 在不反序列化的情况下操作 JSON