模組物件

PyTypeObject PyModule_Type
作為 穩定 ABI 的一部分。

PyTypeObject 的這個例項代表 Python 模組型別。這在 Python 程式中作為 types.ModuleType 公開。

int PyModule_Check(PyObject *p)

如果 p 是模組物件或模組物件的子型別,則返回 true。此函式始終成功。

int PyModule_CheckExact(PyObject *p)

如果 p 是模組物件,但不是 PyModule_Type 的子型別,則返回 true。此函式始終成功。

PyObject *PyModule_NewObject(PyObject *name)
返回值: 新引用。 自 3.7 版本起成為 穩定ABI 的一部分。

返回一個新的模組物件,其 module.__name__ 設定為 name。模組的 __name____doc____package____loader__ 屬性已填充(除了 __name__,其他都設定為 None)。呼叫者負責設定 __file__ 屬性。

如果出錯,返回 NULL 並設定異常。

在 3.3 版本加入。

3.4 版本中已更改: __package____loader__ 現在設定為 None

PyObject *PyModule_New(const char *name)
返回值: 新引用。 穩定ABI 的一部分。

類似於 PyModule_NewObject(),但名稱是 UTF-8 編碼字串而不是 Unicode 物件。

PyObject *PyModule_GetDict(PyObject *module)
返回值: 借用引用。 穩定ABI 的一部分。

返回實現 module 名稱空間的字典物件;此物件與模組物件的 __dict__ 屬性相同。如果 module 不是模組物件(或模組物件的子型別),則會引發 SystemError 並返回 NULL

建議擴充套件使用其他 PyModule_*PyObject_* 函式,而不是直接操作模組的 __dict__

PyObject *PyModule_GetNameObject(PyObject *module)
返回值: 新引用。 自 3.7 版本起成為 穩定ABI 的一部分。

返回 module__name__ 值。如果模組未提供,或者它不是字串,則會引發 SystemError 並返回 NULL

在 3.3 版本加入。

const char *PyModule_GetName(PyObject *module)
作為 穩定 ABI 的一部分。

類似於 PyModule_GetNameObject(),但返回編碼為 'utf-8' 的名稱。

void *PyModule_GetState(PyObject *module)
作為 穩定 ABI 的一部分。

返回模組的“狀態”,即在模組建立時分配的記憶體塊的指標,如果為 NULL 則不返回。請參見 PyModuleDef.m_size

PyModuleDef *PyModule_GetDef(PyObject *module)
作為 穩定 ABI 的一部分。

返回指向建立該模組的 PyModuleDef 結構的指標,如果該模組不是透過定義建立的,則返回 NULL

PyObject *PyModule_GetFilenameObject(PyObject *module)
返回值: 新引用。 穩定ABI 的一部分。

使用 module__file__ 屬性返回載入 module 的檔名。如果未定義,或不是字串,則引發 SystemError 並返回 NULL;否則返回 Unicode 物件的引用。

在 3.2 版本加入。

const char *PyModule_GetFilename(PyObject *module)
作為 穩定 ABI 的一部分。

類似於 PyModule_GetFilenameObject(),但返回編碼為 'utf-8' 的檔名。

3.2 版本中已廢棄: PyModule_GetFilename() 對不可編碼的檔名引發 UnicodeEncodeError,請改用 PyModule_GetFilenameObject()

模組定義

上一節中的函式適用於任何模組物件,包括從 Python 程式碼匯入的模組。

使用 C API 定義的模組通常使用 模組定義,即 PyModuleDef —— 一個靜態分配的常量“描述”,用於說明如何建立模組。

該定義通常用於定義擴充套件的“主”模組物件(有關詳細資訊,請參見 定義擴充套件模組)。它也用於動態建立擴充套件模組

PyModule_New() 不同,該定義允許管理 模組狀態 —— 一塊與模組物件一起分配和清除的記憶體。與模組的 Python 屬性不同,Python 程式碼不能替換或刪除儲存在模組狀態中的資料。

type PyModuleDef
穩定 ABI 的一部分(包括所有成員)。

模組定義結構體,它包含建立模組物件所需的所有資訊。此結構體必須靜態分配(或以其他方式保證在任何從它建立的模組存在期間都有效)。通常,每個擴充套件模組只有一個此型別的變數。

PyModuleDef_Base m_base

此成員始終初始化為 PyModuleDef_HEAD_INIT

const char *m_name

新模組的名稱。

const char *m_doc

模組的文件字串;通常使用 PyDoc_STRVAR 建立的文件字串變數。

Py_ssize_t m_size

模組狀態可以儲存在每個模組的記憶體區域中,可以使用 PyModule_GetState() 檢索,而不是靜態全域性變數。這使得模組可以安全地在多個子直譯器中使用。

此記憶體區域根據 m_size 在模組建立時分配,並在模組物件解除分配時釋放,如果存在 m_free 函式,則在其呼叫之後釋放。

將其設定為非負值表示模組可以重新初始化,並指定其狀態所需的額外記憶體量。

m_size 設定為 -1 表示模組不支援子直譯器,因為它具有全域性狀態。只有在使用 舊版單階段初始化動態建立模組時才允許負值 m_size

有關更多詳細資訊,請參見 PEP 3121

PyMethodDef *m_methods

指向模組級別函式表的指標,由 PyMethodDef 值描述。如果沒有函式,可以為 NULL

PyModuleDef_Slot *m_slots

用於多階段初始化的槽定義陣列,以 {0, NULL} 條目終止。當使用舊版單階段初始化時,m_slots 必須為 NULL

3.5 版本中已更改: 在 3.5 版本之前,此成員始終設定為 NULL,並定義為

inquiry m_reload
traverseproc m_traverse

在模組物件進行 GC 遍歷時呼叫的遍歷函式,如果不需要則為 NULL

如果模組狀態已請求但尚未分配,則不呼叫此函式。這種情況發生在模組建立後立即和模組執行前 (Py_mod_exec 函式)。更準確地說,如果 m_size 大於 0 且模組狀態(由 PyModule_GetState() 返回)為 NULL,則不呼叫此函式。

3.9 版本中已更改: 不再在模組狀態分配之前呼叫。

inquiry m_clear

在模組物件進行 GC 清理時呼叫的清理函式,如果不需要則為 NULL

如果模組狀態已請求但尚未分配,則不呼叫此函式。這種情況發生在模組建立後立即和模組執行前 (Py_mod_exec 函式)。更準確地說,如果 m_size 大於 0 且模組狀態(由 PyModule_GetState() 返回)為 NULL,則不呼叫此函式。

PyTypeObject.tp_clear 一樣,此函式在模組被解除分配之前不 總是 被呼叫。例如,當引用計數足以確定物件不再使用時,不涉及迴圈垃圾回收器,並直接呼叫 m_free

3.9 版本中已更改: 不再在模組狀態分配之前呼叫。

freefunc m_free

在模組物件解除分配時呼叫的函式,如果不需要則為 NULL

如果模組狀態已請求但尚未分配,則不呼叫此函式。這種情況發生在模組建立後立即和模組執行前 (Py_mod_exec 函式)。更準確地說,如果 m_size 大於 0 且模組狀態(由 PyModule_GetState() 返回)為 NULL,則不呼叫此函式。

3.9 版本中已更改: 不再在模組狀態分配之前呼叫。

模組槽位

type PyModuleDef_Slot
int slot

一個槽位 ID,從下面解釋的可用值中選擇。

void *value

槽位的值,其含義取決於槽位 ID。

在 3.5 版本加入。

可用的槽位型別有

Py_mod_create

指定一個函式,該函式用於建立模組物件本身。此槽位的 value 指標必須指向以下簽名的函式:

PyObject *create_module(PyObject *spec, PyModuleDef *def)

該函式接收一個 ModuleSpec 例項,如 PEP 451 中所定義,以及模組定義。它應該返回一個新的模組物件,或者設定錯誤並返回 NULL

此函式應儘量精簡。特別是,它不應呼叫任意 Python 程式碼,因為嘗試再次匯入同一模組可能導致無限迴圈。

在一個模組定義中不能指定多個 Py_mod_create 槽位。

如果未指定 Py_mod_create,則匯入機制將使用 PyModule_New() 建立一個普通模組物件。名稱取自 spec,而不是定義,以允許擴充套件模組動態適應其在模組層次結構中的位置,並透過符號連結以不同的名稱匯入,同時共享單個模組定義。

返回的物件不要求是 PyModule_Type 的例項。只要它支援設定和獲取與匯入相關的屬性,可以使用任何型別。但是,如果 PyModuleDef 具有非 NULLm_traversem_clearm_free;非零的 m_size;或除了 Py_mod_create 之外的槽位,則只能返回 PyModule_Type 例項。

Py_mod_exec

指定一個函式,該函式用於 執行 模組。這相當於執行 Python 模組的程式碼:通常,此函式將類和常量新增到模組中。該函式的簽名為

int exec_module(PyObject *module)

如果指定了多個 Py_mod_exec 槽,它們將按照在 m_slots 陣列中出現的順序進行處理。

Py_mod_multiple_interpreters

指定以下值之一

Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED

該模組不支援在子直譯器中匯入。

Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED

該模組支援在子直譯器中匯入,但僅當它們共享主直譯器的 GIL 時。(請參閱 隔離擴充套件模組。)

Py_MOD_PER_INTERPRETER_GIL_SUPPORTED

該模組支援在子直譯器中匯入,即使它們有自己的 GIL。(請參閱 隔離擴充套件模組。)

此槽位決定在子直譯器中匯入此模組是否會失敗。

在一個模組定義中不能指定多個 Py_mod_multiple_interpreters 槽位。

如果未指定 Py_mod_multiple_interpreters,則匯入機制預設為 Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED

3.12 新版功能.

Py_mod_gil

指定以下值之一

Py_MOD_GIL_USED

模組依賴於全域性直譯器鎖 (GIL) 的存在,並且可以在沒有同步的情況下訪問全域性狀態。

Py_MOD_GIL_NOT_USED

模組可以在沒有活動 GIL 的情況下安全執行。

未配置 --disable-gil 的 Python 構建將忽略此槽位。否則,它將決定匯入此模組是否會導致 GIL 自動啟用。有關詳細資訊,請參見 Free-threaded CPython

在一個模組定義中不能指定多個 Py_mod_gil 槽位。

如果未指定 Py_mod_gil,則匯入機制預設為 Py_MOD_GIL_USED

在 3.13 版本加入。

動態建立擴充套件模組

以下函式可用於在擴充套件的 初始化函式 之外建立模組。它們也用於 單階段初始化

PyObject *PyModule_Create(PyModuleDef *def)
返回值:新引用。

建立一個新的模組物件,給定 def 中的定義。這是一個宏,它呼叫 PyModule_Create2(),其中 module_api_version 設定為 PYTHON_API_VERSION,如果使用受限 API,則設定為 PYTHON_ABI_VERSION

PyObject *PyModule_Create2(PyModuleDef *def, int module_api_version)
返回值: 新引用。 穩定ABI 的一部分。

建立一個新的模組物件,給定 def 中的定義,並假設 API 版本為 module_api_version。如果該版本與執行中的直譯器版本不匹配,則會發出 RuntimeWarning

如果出錯,返回 NULL 並設定異常。

此函式不支援槽位。defm_slots 成員必須為 NULL

備註

此函式的大多數用途都應該使用 PyModule_Create();只有在確定需要時才使用此函式。

PyObject *PyModule_FromDefAndSpec(PyModuleDef *def, PyObject *spec)
返回值:新引用。

此宏呼叫 PyModule_FromDefAndSpec2(),其中 module_api_version 設定為 PYTHON_API_VERSION,如果使用受限 API,則設定為 PYTHON_ABI_VERSION

在 3.5 版本加入。

PyObject *PyModule_FromDefAndSpec2(PyModuleDef *def, PyObject *spec, int module_api_version)
返回值: 新引用。 自 3.7 版本起成為 穩定ABI 的一部分。

建立一個新的模組物件,給定 def 中的定義和模組規格 spec,假設 API 版本為 module_api_version。如果該版本與執行中的直譯器版本不匹配,則會發出 RuntimeWarning

如果出錯,返回 NULL 並設定異常。

請注意,這不處理執行槽位 (Py_mod_exec)。必須同時呼叫 PyModule_FromDefAndSpecPyModule_ExecDef 才能完全初始化模組。

備註

此函式的大多數用途都應該使用 PyModule_FromDefAndSpec();只有在確定需要時才使用此函式。

在 3.5 版本加入。

int PyModule_ExecDef(PyObject *module, PyModuleDef *def)
自 3.7 版本起成為 穩定ABI 的一部分。

處理 def 中給定的任何執行槽 (Py_mod_exec)。

在 3.5 版本加入。

PYTHON_API_VERSION

C API 版本。為向後相容性而定義。

目前,此常量不會在新的 Python 版本中更新,並且對版本控制沒有用。這在將來可能會改變。

PYTHON_ABI_VERSION

定義為 3,以實現向後相容性。

目前,此常量不會在新的 Python 版本中更新,並且對版本控制沒有用。這在將來可能會改變。

支援函式

提供以下函式以幫助初始化模組狀態。它們用於模組的執行槽 (Py_mod_exec)、舊版 單階段初始化 的初始化函式或動態建立模組的程式碼。

int PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value)
自 3.10 版本以來,作為 穩定 ABI 的一部分。

將物件作為 name 新增到 module。這是一個方便的函式,可以在模組的初始化函式中使用。

成功時返回 0。錯誤時,引發異常並返回 -1

用法示例:

static int
add_spam(PyObject *module, int value)
{
    PyObject *obj = PyLong_FromLong(value);
    if (obj == NULL) {
        return -1;
    }
    int res = PyModule_AddObjectRef(module, "spam", obj);
    Py_DECREF(obj);
    return res;
 }

為了方便,此函式接受帶有已設定異常的 NULL value。在這種情況下,返回 -1 並保持已引發的異常不變。

示例也可以不顯式檢查 obj 是否為 NULL

static int
add_spam(PyObject *module, int value)
{
    PyObject *obj = PyLong_FromLong(value);
    int res = PyModule_AddObjectRef(module, "spam", obj);
    Py_XDECREF(obj);
    return res;
 }

請注意,在這種情況下應使用 Py_XDECREF() 而不是 Py_DECREF(),因為 obj 可以為 NULL

傳遞給此函式的不同 name 字串的數量應保持較少,通常僅使用靜態分配的字串作為 name。對於在編譯時未知的名稱,優先直接呼叫 PyUnicode_FromString()PyObject_SetAttr()。有關更多詳細資訊,請參見 PyUnicode_InternFromString(),它可能在內部用於建立鍵物件。

在 3.10 版本加入。

int PyModule_Add(PyObject *module, const char *name, PyObject *value)
自 3.13 版本起成為 穩定 ABI 的一部分。

類似於 PyModule_AddObjectRef(),但“竊取”對 value 的引用。它可以與返回新引用的函式的結果一起呼叫,而無需檢查其結果甚至將其儲存到變數中。

用法示例:

if (PyModule_Add(module, "spam", PyBytes_FromString(value)) < 0) {
    goto error;
}

在 3.13 版本加入。

int PyModule_AddObject(PyObject *module, const char *name, PyObject *value)
作為 穩定 ABI 的一部分。

類似於 PyModule_AddObjectRef(),但成功時(如果返回 0)竊取對 value 的引用。

推薦使用新的 PyModule_Add()PyModule_AddObjectRef() 函式,因為誤用 PyModule_AddObject() 函式很容易引入引用洩漏。

備註

與其他竊取引用的函式不同,PyModule_AddObject() 僅在 成功時 釋放對 value 的引用。

這意味著必須檢查其返回值,並且在錯誤時呼叫程式碼必須手動 Py_XDECREF() value

用法示例:

PyObject *obj = PyBytes_FromString(value);
if (PyModule_AddObject(module, "spam", obj) < 0) {
    // If 'obj' is not NULL and PyModule_AddObject() failed,
    // 'obj' strong reference must be deleted with Py_XDECREF().
    // If 'obj' is NULL, Py_XDECREF() does nothing.
    Py_XDECREF(obj);
    goto error;
}
// PyModule_AddObject() stole a reference to obj:
// Py_XDECREF(obj) is not needed here.

自 3.13 版本棄用: PyModule_AddObject()軟棄用

int PyModule_AddIntConstant(PyObject *module, const char *name, long value)
作為 穩定 ABI 的一部分。

將整數常量作為 name 新增到 module。此便捷函式可用於模組的初始化函式。錯誤時返回 -1 並設定異常,成功時返回 0

這是一個呼叫 PyLong_FromLong()PyModule_AddObjectRef() 的便捷函式;有關詳細資訊,請參見其文件。

int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value)
作為 穩定 ABI 的一部分。

將字串常量作為 name 新增到 module。此便捷函式可用於模組的初始化函式。字串 value 必須以 NULL 終止。錯誤時返回 -1 並設定異常,成功時返回 0

這是一個呼叫 PyUnicode_InternFromString()PyModule_AddObjectRef() 的便捷函式;有關詳細資訊,請參見其文件。

PyModule_AddIntMacro(module, macro)

module 新增一個整數常量。名稱和值取自 macro。例如 PyModule_AddIntMacro(module, AF_INET) 將整數常量 AF_INET 及其值新增到 module。錯誤時返回 -1 並設定異常,成功時返回 0

PyModule_AddStringMacro(module, macro)

module 新增一個字串常量。

int PyModule_AddType(PyObject *module, PyTypeObject *type)
自 3.10 版本以來,作為 穩定 ABI 的一部分。

module 新增一個型別物件。透過內部呼叫 PyType_Ready() 來最終確定型別物件。型別物件的名稱取自 tp_name 點號後的最後一個元件。錯誤時返回 -1 並設定異常,成功時返回 0

在 3.9 版本中新增。

int PyModule_AddFunctions(PyObject *module, PyMethodDef *functions)
自 3.7 版本起成為 穩定ABI 的一部分。

NULL 終止的 functions 陣列中的函式新增到 module。有關各個條目的詳細資訊,請參閱 PyMethodDef 文件(由於缺乏共享模組名稱空間,C 中實現的模組級“函式”通常將模組作為其第一個引數,使其類似於 Python 類上的例項方法)。

當從 PyModuleDef 建立模組時(例如使用 多階段初始化PyModule_CreatePyModule_FromDefAndSpec 時),此函式會自動呼叫。一些模組作者可能更喜歡在多個 PyMethodDef 陣列中定義函式;在這種情況下,他們應該直接呼叫此函式。

在 3.5 版本加入。

int PyModule_SetDocString(PyObject *module, const char *docstring)
自 3.7 版本起成為 穩定ABI 的一部分。

module 的文件字串設定為 docstring。當從 PyModuleDef 建立模組時(例如使用 多階段初始化PyModule_CreatePyModule_FromDefAndSpec 時),此函式會自動呼叫。

在 3.5 版本加入。

int PyUnstable_Module_SetGIL(PyObject *module, void *gil)
這是一個不穩定 API。它可能會在次要版本中未經警告而更改。

指示 module 是否支援在沒有全域性直譯器鎖 (GIL) 的情況下執行,使用 Py_mod_gil 中的某個值。在使用 舊版單階段初始化 時,必須在 module 的初始化函式期間呼叫它。如果此函式在模組初始化期間未被呼叫,則匯入機制假定該模組不支援在沒有 GIL 的情況下執行。此函式僅在配置了 --disable-gil 的 Python 構建中可用。錯誤時返回 -1 並設定異常,成功時返回 0

在 3.13 版本加入。

模組查詢(單階段初始化)

舊版 單階段初始化 方案建立單例模組,可以在當前直譯器的上下文中查詢。這允許稍後僅透過模組定義的引用來檢索模組物件。

這些函式不適用於使用多階段初始化建立的模組,因為可以從單個定義建立多個此類模組。

PyObject *PyState_FindModule(PyModuleDef *def)
返回值: 借用引用。 穩定ABI 的一部分。

返回為當前直譯器從 def 建立的模組物件。此方法要求模組物件已預先使用 PyState_AddModule() 附加到直譯器狀態。如果未找到相應的模組物件或尚未附加到直譯器狀態,則返回 NULL

int PyState_AddModule(PyObject *module, PyModuleDef *def)
自 3.3 版本以來作為 穩定 ABI 的一部分。

將傳遞給函式的模組物件附加到直譯器狀態。這允許透過 PyState_FindModule() 訪問模組物件。

僅對使用單階段初始化建立的模組有效。

Python 在匯入使用 單階段初始化 的模組後會自動呼叫 PyState_AddModule,因此從模組初始化程式碼中呼叫它是不必要的(但無害)。只有當模組自己的初始化程式碼隨後呼叫 PyState_FindModule 時,才需要顯式呼叫。此函式主要用於實現替代匯入機制(透過直接呼叫它,或透過參考其實現來了解所需的狀態更新細節)。

如果之前使用相同的 def 附加了模組,它將被新的 module 替換。

呼叫者必須具有 已附加的執行緒狀態

錯誤時返回 -1 並設定異常,成功時返回 0

在 3.3 版本加入。

int PyState_RemoveModule(PyModuleDef *def)
自 3.3 版本以來作為 穩定 ABI 的一部分。

從直譯器狀態中刪除從 def 建立的模組物件。錯誤時返回 -1 並設定異常,成功時返回 0

呼叫者必須具有 已附加的執行緒狀態

在 3.3 版本加入。