对于Python C扩展,使用Py_DECREF而不是Py_XDECREF有什么好处吗?

对于Python C扩展,使用Py_DECREF而不是Py_XDECREF有什么好处吗?,python,python-c-api,python-c-extension,Python,Python C Api,Python C Extension,我正在阅读定义新类型的PythonC扩展文档,刚刚完成了这一部分 在本节中,他们更改了示例代码,以确保Noddy结构的first和last属性永远不能为NULL,例如,在new中将属性初始化为空字符串,并添加getter和setter,如果用户试图删除或以其他方式将这些属性设置为Null,则会引发TypeError 此外(也是我问题的重点),作者将这些属性的所有Py_XDECREF更改为Py_DECREF,声明: 通过这些更改,我们可以确保第一个和最后一个成员永远不会为NULL,因此我们可以在几

我正在阅读定义新类型的PythonC扩展文档,刚刚完成了这一部分

在本节中,他们更改了示例代码,以确保
Noddy
结构的
first
last
属性永远不能为
NULL
,例如,在
new
中将属性初始化为空字符串,并添加getter和setter,如果用户试图删除或以其他方式将这些属性设置为Null,则会引发
TypeError

此外(也是我问题的重点),作者将这些属性的所有
Py_XDECREF
更改为
Py_DECREF
,声明:

通过这些更改,我们可以确保第一个和最后一个成员永远不会为NULL,因此我们可以在几乎所有情况下删除对NULL值的检查。这意味着大多数Py_XDECREF()调用可以转换为Py_DECREF()调用。我们唯一不能更改这些调用的地方是deallocator,在这里,构造函数中这些成员的初始化可能失败

在我看来,使用
Py_XDECREF
更安全,因为
Py_DECREF
如果传递了
NULL
值,就会导致
分段错误


Py\u XDECREF
上使用
Py\u DECREF
有什么好处?

如果您知道对象不能为空,则在
Py\u XDECREF
上使用
Py\u DECREF
的好处是:

  • 它更快,因为它避免了不必要的测试和跳转
  • 它向(人工)读取器发出信号,指示指针在释放点处应为非空
  • 它提供了一种有效的零成本断言,即指针是非空的-如果不变量被破坏,程序可能会立即崩溃。ª
这些要点在处理低级代码时可能很重要,这就是为什么Python核心和大多数扩展小心地只使用
Py_XDECREF
(或
tp_CLEAR
中的
Py_CLEAR
)而指针实际上可以为空

从技术上讲,这是一种未定义的行为,这意味着不能像实际断言那样保证崩溃。然而,在实践中,编译器别无选择,只能生成取消引用指针的代码,如果指针为空,则会导致内存故障