引用计数

本节中的函数和宏用于管理 Python 对象的引用计数。

Py_ssize_t Py_REFCNT(PyObject *o)

获取 Python 对象 o 的引用计数。

请注意,返回值可能并不真正反映实际持有的对象引用数量。例如,某些对象是“永生”的,并且具有非常高的引用计数,并不反映实际的引用数量。因此,不要依赖返回值的准确性,除非值为 0 或 1。

使用 Py_SET_REFCNT() 函数来设置对象的引用计数。

在版本 3.10 中更改: Py_REFCNT() 更改为内联静态函数。

在版本 3.11 中更改: 参数类型不再是 const PyObject*.

void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt)

将对象 o 的引用计数设置为 refcnt

请注意,此函数对 永生 对象没有影响。

在版本 3.9 中添加。

在版本 3.12 中更改: 永生对象不会被修改。

void Py_INCREF(PyObject *o)

表示对对象 o 进行新的 强引用,表明它正在使用中,不应被销毁。

此函数通常用于将 借用引用 就地转换为 强引用Py_NewRef() 函数可用于创建新的 强引用

使用完对象后,通过调用 Py_DECREF() 来释放它。

对象不能为 NULL;如果您不确定它是否为 NULL,请使用 Py_XINCREF()

不要期望此函数实际修改 o。对于至少 某些对象,此函数没有效果。

在版本 3.12 中更改: 永生对象不会被修改。

void Py_XINCREF(PyObject *o)

类似于 Py_INCREF(),但对象 o 可以为 NULL,在这种情况下,它没有效果。

另请参阅 Py_XNewRef().

PyObject *Py_NewRef(PyObject *o)
自 3.10 版本起,成为 稳定 ABI 的一部分。

创建一个对对象的新的 强引用:对 o 调用 Py_INCREF() 并返回对象 o

当不再需要 强引用 时,应在它上面调用 Py_DECREF() 以释放引用。

对象 o 必须不能为 NULL;如果 o 可能为 NULL,请使用 Py_XNewRef()

例如

Py_INCREF(obj);
self->attr = obj;

可以写成

self->attr = Py_NewRef(obj);

另请参阅 Py_INCREF().

在 3.10 版本中添加。

PyObject *Py_XNewRef(PyObject *o)
自 3.10 版本起,成为 稳定 ABI 的一部分。

类似于 Py_NewRef(),但对象 o 可以为 NULL。

如果对象 oNULL,该函数只返回 NULL

在 3.10 版本中添加。

void Py_DECREF(PyObject *o)

释放对对象 o强引用,表明不再使用该引用。

一旦最后一个 强引用 被释放(即对象的引用计数达到 0),对象的类型的释放函数(不能为 NULL)将被调用。

此函数通常用于在退出其范围之前删除 强引用

对象必须不能为 NULL;如果您不确定它是否为 NULL,请使用 Py_XDECREF()

不要期望此函数实际修改 o。对于至少 某些对象,此函数没有效果。

警告

释放函数可能会导致任意 Python 代码被调用(例如,当具有 __del__() 方法的类实例被释放时)。虽然此类代码中的异常不会传播,但执行的代码可以自由访问所有 Python 全局变量。这意味着,在调用 Py_DECREF() 之前,从全局变量可访问的任何对象都应该处于一致状态。例如,删除列表中对象的代码应该将对要删除对象的引用复制到一个临时变量中,更新列表数据结构,然后对临时变量调用 Py_DECREF()

在版本 3.12 中更改: 永生对象不会被修改。

void Py_XDECREF(PyObject *o)

类似于 Py_DECREF(),但对象 o 可以是 NULL,在这种情况下,它没有任何效果。来自 Py_DECREF() 的相同警告也适用于此。

void Py_CLEAR(PyObject *o)

释放对对象 o强引用。该对象可以是 NULL,在这种情况下,宏没有任何效果;否则,其效果与 Py_DECREF() 相同,除了参数也被设置为 NULL。对于 Py_DECREF() 的警告不适用于传递的对象,因为宏谨慎地使用了临时变量并在释放引用之前将参数设置为 NULL

在释放对可能在垃圾回收期间被遍历的对象的引用时,使用此宏是一个好主意。

在 3.12 版本中更改: 宏参数现在只会被评估一次。如果参数有副作用,这些副作用将不再重复。

void Py_IncRef(PyObject *o)
稳定 ABI 的一部分。

指示对对象 o 获取新的 强引用Py_XINCREF() 的函数版本。它可用于 Python 的运行时动态嵌入。

void Py_DecRef(PyObject *o)
稳定 ABI 的一部分。

释放对对象o强引用。这是Py_XDECREF()的函数版本。它可用于 Python 的运行时动态嵌入。

Py_SETREF(dst, src)

宏安全地释放对对象dst强引用并将dst设置为src

Py_CLEAR()的情况一样,“显而易见”的代码可能是致命的

Py_DECREF(dst);
dst = src;

安全的方法是

Py_SETREF(dst, src);

这样安排在释放对dst旧值的引用之前将dst设置为src,因此任何因dst被拆除而触发的代码不再认为dst指向有效对象。

在版本 3.6 中添加。

在版本 3.12 中更改:宏参数现在只会被评估一次。如果参数有副作用,这些副作用将不再重复。

Py_XSETREF(dst, src)

Py_SETREF宏的变体,它使用Py_XDECREF()而不是Py_DECREF().

在版本 3.6 中添加。

在版本 3.12 中更改:宏参数现在只会被评估一次。如果参数有副作用,这些副作用将不再重复。