模块对象¶
-
PyTypeObject PyModule_Type¶
- 作为 稳定 ABI 的一部分。
此
PyTypeObject
实例表示 Python 模块类型。它在 Python 程序中以types.ModuleType
的形式公开。
-
int PyModule_CheckExact(PyObject *p)¶
如果 p 是模块对象,但不是
PyModule_Type
的子类型,则返回 True。此函数始终成功。
-
PyObject *PyModule_NewObject(PyObject *name)¶
- 返回值:新引用。 作为 稳定 ABI 的一部分,从版本 3.7 开始。
返回一个新的模块对象,其
__name__
属性设置为 name。模块的__name__
、__doc__
、__package__
和__loader__
属性将被填充(除了__name__
之外,所有属性都设置为None
);调用者负责提供__file__
属性。在版本 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)¶
- 返回值:新引用。 作为 稳定 ABI 的一部分,从版本 3.7 开始。
返回 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的文件名。如果此属性未定义,或者不是Unicode字符串,则引发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 中的定义。这与
PyModule_Create2()
相似,其中 module_api_version 设置为PYTHON_API_VERSION
。
-
PyObject *PyModule_Create2(PyModuleDef *def, int module_api_version)¶
- 返回值:新引用。 是 稳定 ABI 的一部分。
创建一个新的模块对象,给定 def 中的定义,假设 API 版本 module_api_version。如果该版本与正在运行的解释器的版本不匹配,则会发出
RuntimeWarning
。注意
大多数使用此函数的情况应该使用
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 对象,它能正确报告其类型和引用计数。
返回def强制转换为
PyObject*
,如果发生错误则返回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 模块的代码:通常,此函数将类和常量添加到模块中。函数的签名是
-
int exec_module(PyObject *module)
如果指定了多个
Py_mod_exec
插槽,它们将按照它们在m_slots数组中出现的顺序进行处理。-
int exec_module(PyObject *module)
-
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¶
有关多阶段初始化的更多详细信息,请参见 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)¶
- 返回值:新引用。 作为 稳定 ABI 的一部分,从版本 3.7 开始。
创建一个新的模块对象,给定 def 中的定义和 ModuleSpec spec,假设 API 版本为 module_api_version。如果该版本与正在运行的解释器的版本不匹配,则会发出
RuntimeWarning
。注意
此函数的大多数用法都应该使用
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
,则返回NULL
。在这种情况下,必须调用它并引发异常。示例用法
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
。在版本 3.10 中添加。
-
int PyModule_AddObject(PyObject *module, const char *name, PyObject *value)¶
- 作为 稳定 ABI 的一部分。
类似于
PyModule_AddObjectRef()
,但在成功时(如果返回0
)会窃取对 value 的引用。建议使用新的
PyModule_AddObjectRef()
函数,因为它很容易通过误用PyModule_AddObject()
函数引入引用泄漏。注意
与其他窃取引用的函数不同,
PyModule_AddObject()
仅在成功时才会释放对 value 的引用。这意味着必须检查其返回值,并且调用代码必须在出错时手动
Py_DECREF()
value。示例用法
static int add_spam(PyObject *module, int value) { PyObject *obj = PyLong_FromLong(value); if (obj == NULL) { return -1; } if (PyModule_AddObject(module, "spam", obj) < 0) { Py_DECREF(obj); return -1; } // PyModule_AddObject() stole a reference to obj: // Py_DECREF(obj) is not needed here return 0; }
示例也可以在不显式检查 obj 是否为
NULL
的情况下编写static int add_spam(PyObject *module, int value) { PyObject *obj = PyLong_FromLong(value); if (PyModule_AddObject(module, "spam", obj) < 0) { Py_XDECREF(obj); return -1; } // PyModule_AddObject() stole a reference to obj: // Py_DECREF(obj) is not needed here return 0; }
请注意,在这种情况下,应使用
Py_XDECREF()
而不是Py_DECREF()
,因为 obj 可能为NULL
。
-
int PyModule_AddIntConstant(PyObject *module, const char *name, long value)¶
- 作为 稳定 ABI 的一部分。
在module中添加一个名为name的整型常量。此便捷函数可以在模块的初始化函数中使用。如果出错,返回
-1
,如果成功,返回0
。
-
int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value)¶
- 作为 稳定 ABI 的一部分。
在module中添加一个名为name的字符串常量。此便捷函数可以在模块的初始化函数中使用。字符串value必须以
NULL
结尾。如果出错,返回-1
,如果成功,返回0
。
-
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 版本中添加。
模块查找¶
单阶段初始化创建单例模块,这些模块可以在当前解释器的上下文中查找。这允许模块对象稍后仅通过对模块定义的引用来检索。
这些函数不适用于使用多阶段初始化创建的模块,因为可以从单个定义创建多个此类模块。
-
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
,因此在模块初始化代码中调用它是没有必要的(但无害)。只有当模块自己的 init 代码随后调用PyState_FindModule
时,才需要显式调用。该函数主要用于实现替代的导入机制(通过直接调用它,或参考它的实现来了解所需的 state 更新的详细信息)。调用者必须持有 GIL。
成功返回 0,失败返回 -1。
在版本 3.3 中添加。
-
int PyState_RemoveModule(PyModuleDef *def)¶
- 自 3.3 版本起,成为 稳定 ABI 的一部分。
从解释器状态中删除由 def 创建的模块对象。成功返回 0,失败返回 -1。
调用者必须持有 GIL。
在版本 3.3 中添加。