參照計數

本節中的函式與巨集用於管理 Python 物件的參照計數。

Py_ssize_t Py_REFCNT(PyObject *o)

取得物件 o 的參照計數。

請注意,回傳的值可能實際上並不反映實際保存了多少對該物件的參照。例如,某些物件是「不滅的 (immortal)」,並且具有非常高的參照計數,不能反映實際的參照數量。因此,除了 0 或 1 以外,不要依賴回傳值的準確性。

使用 Py_SET_REFCNT() 函式設定物件參照計數。

在 3.10 版的變更: Py_REFCNT() 更改為行內靜態函式 (inline static function)。

在 3.11 版的變更: 參數型別不再是 const PyObject*

void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt)

設定物件 o 的參照計數。

On Python build with Free Threading, if refcnt is larger than UINT32_MAX, the object is made immortal.

請注意,此函式對不滅的物件沒有影響。

在 3.9 版被加入.

在 3.12 版的變更: 不滅的物件不會被修改。

void Py_INCREF(PyObject *o)

代表取得對於物件 o 的新強參照,即它正在使用且不應被銷毀。

請注意,此函式對不滅的物件沒有影響。

此函式通常用於將借用參照原地 (in-place) 轉換為強參照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)
穩定 ABI 的一部分 自 3.10 版本開始.

建立對物件的新強參照:於 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)
穩定 ABI 的一部分 自 3.10 版本開始.

Py_NewRef() 類似,但物件 o 可以為 NULL。

如果物件 oNULL,則該函式僅回傳 NULL

在 3.10 版被加入.

void Py_DECREF(PyObject *o)

釋放一個對物件 o強參照,代表該參照不會再被使用。

請注意,此函式對不滅的物件沒有影響。

如果最後一個強參照被釋放(即物件的參照計數達到零),則觸發物件之型別的釋放函式 (deallocation function)(不得為 NULL)。

此函式通常用於在退出作用域之前刪除強參照

該物件不能為 NULL;如果你不確定它不是 NULL,請改用 Py_XDECREF()

不要期望此函式會以任何方式實際修改 o,至少對於某些物件來說,此函式沒有任何效果。

警告

釋放函式可以導致任意 Python 程式碼被調用(例如,當釋放具有 __del__() 方法的類別實例時)。雖然此類程式碼中的例外不會被傳遞出來,但​​執行的程式碼可以自由存取所有 Python 全域變數。這意味著在調用 Py_DECREF() 之前,可從全域變數存取的任何物件都應處於一致狀態。例如,從 list 中刪除物件的程式碼應將已刪除物件的參照複製到臨時變數中,更新 list 資料結構,然後為臨時變數呼叫 Py_DECREF()

在 3.12 版的變更: 不滅的物件不會被修改。

void Py_XDECREF(PyObject *o)

Py_DECREF() 類似,但該物件可以是 NULL,在這種情況下巨集不起作用。在這裡也會出現與 Py_DECREF() 相同的警告。

void Py_CLEAR(PyObject *o)

釋放對於物件 o強參照。該物件可能是 NULL,在這種情況下巨集不起作用;否則,效果與 Py_DECREF() 相同,除非引數也設定為 NULLPy_DECREF() 的警告不適用於傳遞的物件,因為巨集在釋放其參照之前小心地使用臨時變數並將引數設定為 NULL

每當要釋放垃圾回收 (garbage collection) 期間可能被遍歷到之對於物件的參照時,使用此巨集是個好主意。

在 3.12 版的變更: 巨集引數現在僅會被求值 (evaluate) 一次。如果引數有其他副作用,則不再重複作用。

void Py_IncRef(PyObject *o)
穩定 ABI 的一部分.

代表取得對於物件 o強參照Py_XINCREF() 的函式版本。它可用於 Python 的 runtime 動態嵌入。

void Py_DecRef(PyObject *o)
穩定 ABI 的一部分.

釋放對物件 o強參照Py_XDECREF() 的函式版本。它可用於 Python 的 runtime 動態嵌入。

Py_SETREF(dst, src)

巨集安全地釋放對於物件 dst強參照並將 dst 設定為 src

Py_CLEAR() 的情況一樣,「明顯的」程式碼可能是致命的:

Py_DECREF(dst);
dst = src;

安全的方法是:

Py_SETREF(dst, src);

這會在釋放對 dst 舊值的參照_之前_將 dst 設定為 src,使得因 dst 被拆除而觸發的任何副作用 (side-effect) 之程式碼不會相信 dst 是指向一個有效物件。

在 3.6 版被加入.

在 3.12 版的變更: 巨集引數現在僅會被求值一次。如果引數有其他副作用,則不再重複作用。

Py_XSETREF(dst, src)

Py_SETREF 巨集的變體,請改用 Py_XDECREF() 而非 Py_DECREF()

在 3.6 版被加入.

在 3.12 版的變更: 巨集引數現在僅會被求值一次。如果引數有其他副作用,則不再重複作用。