python - 为什么我们几乎总是要在减少引用计数之前重新分配对象成员?
问题描述
我正在阅读本教程,以了解如何编写 C 扩展模块来定义新类型。在某些时候,给出了以下tp_init
实现:
static int
Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
{
static char *kwlist[] = {"first", "last", "number", NULL};
PyObject *first = NULL, *last = NULL, *tmp;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
&first, &last,
&self->number))
return -1;
if (first) {
tmp = self->first;
Py_INCREF(first);
self->first = first;
Py_XDECREF(tmp);
}
if (last) {
tmp = self->last;
Py_INCREF(last);
self->last = last;
Py_XDECREF(tmp);
}
return 0;
}
我面临的麻烦是我看不出像这样分配第一个成员有什么害处:
if (first) {
Py_XDECREF(self->first);
Py_INCREF(first);
self->first = first;
}
另一方面,上述教程警告我们不要使用它,因为:
我们的类型不限制第一个成员的类型,所以它可以是任何类型的对象。它可能有一个析构函数,导致代码被执行,试图访问第一个成员
它还继续说:
为了偏执并保护自己免受这种可能性的影响,我们几乎总是在减少引用计数之前重新分配成员
考虑到这些警告,我仍然看不出这两种方式之间有任何实际差异。first
那么,为什么在减少旧的 PyObject 引用计数之前,我应该使用第一个将成员重新分配给新 PyObject 的方法?
解决方案
推荐阅读
- mysql - 我想了解mysql中的AUTO_INCREMENT值
- c++ - 如何解决或修复 C++98 'v' 中 (dev cpp) [Error] 中的此错误必须由构造函数初始化,而不是由 '{...}'
- java - firebase 电话号码身份验证获取空参考
- windows - 将文件移动到子目录
- python - 在日期条件下删除具有相同 ID 的数据框中的特定列
- multithreading - 将 vtkImageData 复制到另一个 vtkImageData
- c - 为什么最大堆栈深度不断变化?
- docker - Azure DevOps CI 与容器的 Web 应用程序
- python - spacy NLP 如何在这种情况下提取信息
- sql - PostgreSQL 使用内连接删除重复行