引用計數

本節中的函式和宏用於管理 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 版本中的更改: 宏引數現在只評估一次。如果引數有副作用,則不再重複。