引用计数

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

Py_ssize_t Py_REFCNT(PyObject *o)
自 3.14 版本以来,作为 稳定 ABI 的一部分。

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

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

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

备注

自由线程 Python 构建中,返回 1 不足以确定是否可以安全地将 o 视为没有其他线程访问。请改用 PyUnstable_Object_IsUniquelyReferenced()

另请参阅函数 PyUnstable_Object_IsUniqueReferencedTemporary()

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

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

void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt)

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

启用自由线程的 Python 构建 中,如果 refcnt 大于 UINT32_MAX,则该对象将变为不朽的

此函数对不朽对象无效。

在 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 版本中的更改: 宏参数现在只评估一次。如果参数有副作用,则不再重复。