python - python解释器如何处理对象的负引用计数?

标签 python python-c-api

如果对象的引用计数为负数,python 解释器会释放对象的内存吗?

例如,如果我有这样的代码,time_tuple 会被 python 释放吗?

PyObject* list = PyList_New(2);
PyObject *time_tuple = Py_BuildValue("(s, s)", "Time", "O");
PyList_SetItem(list, 0, time_tuple);
Py_XDECREF(time_tuple);
Py_XDECREF(list);

如果可以,请在回答中引用一些文档。

最佳答案

解释器不应该遇到负引用计数。如果引用计数达到零,则意味着对该对象的引用为零。一旦发生这种情况,该对象将被释放。

引用 Python documentation :

If the reference count reaches zero, the object’s type’s deallocation function (which must not be NULL) is invoked.

另见 here了解更多。

同样重要的是要注意,在 Python 中,除了引用计数之外,跟踪谁实际拥有这些引用也很重要。

在您提供的示例中:

  1. Py_BuildValue() 返回一个新的引用,然后由您拥有并保存在 time_tuple 中。此时元组的引用计数为 1。

  2. PyList_SetItem() 窃取了所有权引用,元组的引用计数仍然为 1,但引用归 list 所有。

  3. Py_XDECREF(time_tuple) 将元组的引用计数递减为 0,并释放对象。这是一个错误,因为引用属于list

  4. Py_XDECREF(list) 将列表的引用计数递减为 0,并释放列表。对元组的引用归列表所有,因此它会减少其引用计数。

  5. 不幸的是,元组已经分配完毕,您的程序崩溃了。或者更糟的是,它可能会继续运行一段时间,并在代码的不相关部分崩溃。对此进行调试通常很有趣。

关于python - python解释器如何处理对象的负引用计数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24571093/

相关文章:

python - 将 Django TimeField 与时区感知日期时间进行比较;将原始时间与 timezone.now() 进行比较

python - 编译多个模块时 import_array() 出现 Numpy/CAPI 错误

python - 通过 C API 在 Python 模块中定义全局变量

Python C 扩展 - 在每个纯 C 调用周围添加 Py_BEGIN_ALLOW_THREADS 有什么危害?

python - 第二次调用时无法从python模块获取该函数

Python C API : how to get string representation of exception?

javascript - 使用 JAVAScript 从 Phonegap 应用程序向 DJANGO 提交表单

python - 网格数据插值

python - 使用正则表达式输入创建列表

python - 创建二维字符串数组