模組物件¶
-
PyTypeObject PyModule_Type¶
- 屬於 穩定 ABI 的一部分。
這個
PyTypeObject
的例項表示 Python 模組型別。它作為types.ModuleType
暴露給 Python 程式。
-
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
。
-
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 版本中更改: 在分配模組狀態之前不再呼叫。
-
PyModuleDef_Base m_base¶
單階段初始化¶
模組初始化函式可以直接建立並返回模組物件。這稱為“單階段初始化”,並使用以下兩個模組建立函式之一
-
PyObject *PyModule_Create(PyModuleDef *def)¶
- 返回值:新引用。
給定 def 中的定義,建立一個新的模組物件。這與將 module_api_version 設定為
PYTHON_API_VERSION
的PyModule_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
結構的陣列
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
具有非NULL
的m_traverse
、m_clear
、m_free
;非零的m_size
;或除了Py_mod_create
之外的槽,則只能返回PyModule_Type
例項。-
PyObject *create_module(PyObject *spec, PyModuleDef *def)¶
-
Py_mod_exec¶
指定一個被呼叫以執行模組的函式。這等效於執行 Python 模組的程式碼:通常,此函式會將類和常量新增到模組中。該函式的簽名是
如果指定了多個
Py_mod_exec
槽,則它們會按照它們在 m_slots 陣列中出現的順序進行處理。
-
Py_mod_multiple_interpreters¶
指定以下值之一
-
Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED¶
該模組不支援在子直譯器中匯入。
此槽確定在子直譯器中匯入此模組是否會失敗。
一個模組定義中不能指定多個
Py_mod_multiple_interpreters
槽。如果未指定
Py_mod_multiple_interpreters
,則匯入機制預設為Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED
。在 3.12 版本中新增。
-
Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED¶
-
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 版本中新增。
-
Py_MOD_GIL_USED¶
有關多階段初始化的更多詳細資訊,請參閱 PEP 489。
底層模組建立函式¶
以下函式在使用多階段初始化時在底層被呼叫。它們可以直接使用,例如在動態建立模組物件時。請注意,必須呼叫 PyModule_FromDefAndSpec
和 PyModule_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_Create
或PyModule_FromDefAndSpec
從PyModuleDef
建立模組時,會自動呼叫此函式。在 3.5 版本中新增。
-
int PyModule_AddFunctions(PyObject *module, PyMethodDef *functions)¶
- 自 3.7 版本起成為 穩定 ABI 的一部分。
將以
NULL
結尾的 functions 陣列中的函式新增到 module。有關各個條目的詳細資訊,請參閱PyMethodDef
文件(由於缺少共享的模組名稱空間,用 C 實現的模組級“函式”通常會接收模組作為其第一個引數,使其類似於 Python 類上的例項方法)。當使用PyModule_Create
或PyModule_FromDefAndSpec
從PyModuleDef
建立模組時,會自動呼叫此函式。在 3.5 版本中新增。
支援函式¶
模組初始化函式(如果使用單階段初始化)或從模組執行槽呼叫的函式(如果使用多階段初始化)可以使用以下函式來幫助初始化模組狀態
-
int PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value)¶
- 自 3.10 版本起成為 穩定 ABI 的一部分。
將物件作為 name 新增到 module。這是一個方便函式,可以從模組的初始化函式中使用。
成功時,返回
0
。發生錯誤時,引發異常並返回-1
。如果 value 為
NULL
,則返回-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 版本中新增。