引用計數¶
本節中的函式和宏用於管理 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。
在啟用自由執行緒的 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。如果物件 o 為
NULL
,則函式僅返回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 版本中變更: 宏引數現在只會被求值一次。如果引數有副作用,這些副作用將不再重複執行。