模組物件¶
-
PyTypeObject PyModule_Type¶
- 作為 穩定 ABI 的一部分。
PyTypeObject
的這個例項代表 Python 模組型別。這在 Python 程式中作為types.ModuleType
公開。
-
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
。
-
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¶
模組槽位¶
可用的槽位型別有
-
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_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 自動啟用。有關詳細資訊,請參見 Free-threaded CPython。在一個模組定義中不能指定多個
Py_mod_gil
槽位。如果未指定
Py_mod_gil
,則匯入機制預設為Py_MOD_GIL_USED
。在 3.13 版本加入。
-
Py_MOD_GIL_USED¶
動態建立擴充套件模組¶
以下函式可用於在擴充套件的 初始化函式 之外建立模組。它們也用於 單階段初始化。
-
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
並設定異常。此函式不支援槽位。def 的
m_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_FromDefAndSpec
和PyModule_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_Create
或PyModule_FromDefAndSpec
時),此函式會自動呼叫。一些模組作者可能更喜歡在多個PyMethodDef
陣列中定義函式;在這種情況下,他們應該直接呼叫此函式。在 3.5 版本加入。
-
int PyModule_SetDocString(PyObject *module, const char *docstring)¶
- 自 3.7 版本起成為 穩定ABI 的一部分。
將 module 的文件字串設定為 docstring。當從
PyModuleDef
建立模組時(例如使用 多階段初始化、PyModule_Create
或PyModule_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 版本加入。