模組物件

PyTypeObject PyModule_Type
屬於 穩定 ABI 的一部分。

這個 PyTypeObject 的例項表示 Python 模組型別。它作為 types.ModuleType 暴露給 Python 程式。

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()

初始化 C 模組

模組物件通常從擴充套件模組(匯出初始化函式的共享庫)或編譯到內建模組(使用 PyImport_AppendInittab() 新增初始化函式)建立。 請參閱 構建 C 和 C++ 擴充套件擴充套件嵌入式 Python 瞭解詳細資訊。

初始化函式可以將模組定義例項傳遞給 PyModule_Create(),並返回生成的模組物件,或者透過返回定義結構本身來請求“多階段初始化”。

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 版本中更改: 在分配模組狀態之前不再呼叫。

單階段初始化

模組初始化函式可以直接建立並返回模組物件。這稱為“單階段初始化”,並使用以下兩個模組建立函式之一

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

給定 def 中的定義,建立一個新的模組物件。這與將 module_api_version 設定為 PYTHON_API_VERSIONPyModule_Create2() 的行為類似。

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

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

如果發生錯誤,則返回 NULL 並設定異常。

注意

大多數使用此函式的場景都應該使用 PyModule_Create() 代替;僅在確定需要時才使用此函式。

在從初始化函式返回之前,通常使用 PyModule_AddObjectRef() 等函式填充生成的模組物件。

多階段初始化

指定擴充套件的另一種方法是請求“多階段初始化”。以這種方式建立的擴充套件模組的行為更像 Python 模組:初始化在模組物件建立時的建立階段和填充時的執行階段之間分開。這種區別類似於類的 __new__()__init__() 方法。

與使用單階段初始化建立的模組不同,這些模組不是單例:如果刪除了 sys.modules 條目並重新匯入該模組,則會建立一個新的模組物件,並且舊模組會像 Python 模組一樣進行正常的垃圾回收。預設情況下,從同一定義建立的多個模組應該是獨立的:對一個模組的更改不應影響其他模組。這意味著所有狀態都應特定於模組物件(例如,使用 PyModule_GetState()),或其內容(例如模組的 __dict__ 或使用 PyType_FromSpec() 建立的單個類)。

所有使用多階段初始化建立的模組都應支援子直譯器。確保多個模組獨立通常足以實現這一點。

要請求多階段初始化,初始化函式(PyInit_modulename)返回一個 PyModuleDef 例項,其中非空的 m_slots。在返回之前,必須使用以下函式初始化 PyModuleDef 例項

PyObject *PyModuleDef_Init(PyModuleDef *def)
返回值:借用的引用。自 3.5 版本起,屬於穩定 ABI的一部分。

確保模組定義是正確初始化的 Python 物件,可以正確報告其型別和引用計數。

返回強制轉換為 PyObject*def,如果發生錯誤,則返回 NULL

在 3.5 版本中新增。

模組定義的 m_slots 成員必須指向 PyModuleDef_Slot 結構的陣列

type PyModuleDef_Slot
int slot

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

void *value

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

在 3.5 版本中新增。

m_slots 陣列必須以 ID 為 0 的槽終止。

可用的槽型別是

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_NOT_SUPPORTED

在 3.12 版本中新增。

Py_mod_gil

指定以下值之一

Py_MOD_GIL_USED

該模組依賴於全域性直譯器鎖(GIL)的存在,並且可以訪問全域性狀態而無需同步。

Py_MOD_GIL_NOT_USED

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

此槽會被未配置 --disable-gil 的 Python 構建忽略。否則,它會確定匯入此模組是否會導致 GIL 自動啟用。有關更多詳細資訊,請參閱自由執行緒 CPython

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

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

在 3.13 版本中新增。

有關多階段初始化的更多詳細資訊,請參閱 PEP 489

底層模組建立函式

以下函式在使用多階段初始化時在底層被呼叫。它們可以直接使用,例如在動態建立模組物件時。請注意,必須呼叫 PyModule_FromDefAndSpecPyModule_ExecDef 才能完全初始化模組。

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

給定 def 中的定義和 ModuleSpec spec,建立一個新的模組物件。此行為類似於 PyModule_FromDefAndSpec2(),其中 module_api_version 設定為 PYTHON_API_VERSION

在 3.5 版本中新增。

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

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

如果發生錯誤,則返回 NULL 並設定異常。

注意

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

在 3.5 版本中新增。

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

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

在 3.5 版本中新增。

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

module 的文件字串設定為 docstring。當使用 PyModule_CreatePyModule_FromDefAndSpecPyModuleDef 建立模組時,會自動呼叫此函式。

在 3.5 版本中新增。

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

將以 NULL 結尾的 functions 陣列中的函式新增到 module。有關各個條目的詳細資訊,請參閱 PyMethodDef 文件(由於缺少共享的模組名稱空間,用 C 實現的模組級“函式”通常會接收模組作為其第一個引數,使其類似於 Python 類上的例項方法)。當使用 PyModule_CreatePyModule_FromDefAndSpecPyModuleDef 建立模組時,會自動呼叫此函式。

在 3.5 版本中新增。

支援函式

模組初始化函式(如果使用單階段初始化)或從模組執行槽呼叫的函式(如果使用多階段初始化)可以使用以下函式來幫助初始化模組狀態

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

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

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

如果 valueNULL,則返回 -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;
 }

也可以在不顯式檢查 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 的一部分。

將字串常量 value 作為 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 PyUnstable_Module_SetGIL(PyObject *module, void *gil)
這是 不穩定 API。它可能會在次要版本中更改,恕不另行通知。

使用 Py_mod_gil 中的一個值來指示 module 是否支援在沒有全域性直譯器鎖 (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 時才需要顯式呼叫。該函式主要用於實現替代的匯入機制(透過直接呼叫它,或透過參考其實現來了解所需的狀態更新的詳細資訊)。

呼叫者必須持有 GIL。

如果發生錯誤,返回 -1 並設定一個異常,成功時返回 0

在 3.3 版本中新增。

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

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

呼叫者必須持有 GIL。

在 3.3 版本中新增。