模块对象

PyTypeObject PyModule_Type

此实例 PyTypeObject 表示python模块类型。这对python程序公开为 types.ModuleType .

int PyModule_Check(PyObject *p)

如果满足以下条件,则返回TRUE p 是模块对象,或者是模块对象的子类型。此功能总是成功的。

int PyModule_CheckExact(PyObject *p)

如果满足以下条件,则返回TRUE p 是模块对象,但不是 PyModule_Type 。此功能总是成功的。

PyObject *PyModule_NewObject(PyObject *name)
Return value: New reference.

用返回新的模块对象 __name__ 属性设置为 name . 模块的 __name____doc____package____loader__ 填写属性(除 __name__ 设置为 None );调用者负责提供 __file__ 属性。

3.3 新版功能.

在 3.4 版更改: __package____loader__ 设置为 None .

PyObject *PyModule_New(const char *name)
Return value: New reference.

类似 PyModule_NewObject() 但名称是一个UTF-8编码的字符串,而不是Unicode对象。

PyObject *PyModule_GetDict(PyObject *module)
Return value: Borrowed reference.

返回实现的Dictionary对象 模块 的命名空间;此对象与 __dict__ 模块对象的属性。如果 模块 不是模块对象(或模块对象的子类型), SystemError 被抚养和 NULL 返回。

建议扩展使用其他 PyModule_*PyObject_* 函数而不是直接操作模块的 __dict__ .

PyObject *PyModule_GetNameObject(PyObject *module)
Return value: New reference.

返回 模块__name__ 价值。如果模块没有提供,或者不是字符串, SystemError 被抚养和 NULL 返回。

3.3 新版功能.

const char *PyModule_GetName(PyObject *module)

类似 PyModule_GetNameObject() 但返回编码的名称 'utf-8' .

void *PyModule_GetState(PyObject *module)

返回模块的“状态”,即指向模块创建时分配的内存块的指针,或 NULL . 见 PyModuleDef.m_size .

PyModuleDef *PyModule_GetDef(PyObject *module)

返回指向 PyModuleDef 从中创建模块的结构,或 NULL 如果模块不是根据定义创建的。

PyObject *PyModule_GetFilenameObject(PyObject *module)
Return value: New reference.

返回文件名,其中 模块 使用加载 模块__file__ 属性。如果未定义或不是Unicode字符串,则引发 SystemError 然后返回 NULL ;否则返回对Unicode对象的引用。

3.2 新版功能.

const char *PyModule_GetFilename(PyObject *module)

类似 PyModule_GetFilenameObject() 但返回编码为“utf-8”的文件名。

3.2 版后已移除: PyModule_GetFilename() 引发 UnicodeEncodeError 在不可编码的文件名上,使用 PyModule_GetFilenameObject() 相反。

初始化C模块

模块对象通常是从扩展模块(导出初始化函数的共享库)创建的,或者在模块中编译(在模块中使用 PyImport_AppendInittab() )见 构建C和C++扩展扩展嵌入式python 有关详细信息。

初始化函数可以将模块定义实例传递给 PyModule_Create() ,并返回生成的模块对象,或者通过返回定义结构本身来请求“多阶段初始化”。

type PyModuleDef

模块定义结构,它保存创建模块对象所需的所有信息。对于每个模块,通常只有一个这种类型的静态初始化变量。

PyModuleDef_Base m_base

始终将此成员初始化为 PyModuleDef_HEAD_INIT .

const char *m_name

新模块的名称。

const char *m_doc

模块的docstring;通常是用 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清除模块对象期间调用的clear函数,或 NULL 如果不需要的话。

如果模块状态已请求但尚未分配,则不调用此函数。这是在模块创建之后和执行之前的情况 (Py_mod_exec 功能)。更准确地说,如果 m_size 大于0且模块状态(由返回 PyModule_GetState()NULL .

在 3.9 版更改: 在分配模块状态之前不再调用。

freefunc m_free

在释放模块对象期间要调用的函数,或 NULL 如果不需要的话。

如果模块状态已请求但尚未分配,则不调用此函数。这是在模块创建之后和执行之前的情况 (Py_mod_exec 功能)。更准确地说,如果 m_size 大于0且模块状态(由返回 PyModule_GetState()NULL .

在 3.9 版更改: 在分配模块状态之前不再调用。

单相初始化

模块初始化功能可以直接创建和返回模块对象。这被称为“单相初始化”,使用以下两个模块创建功能之一:

PyObject *PyModule_Create(PyModuleDef *def)
Return value: New reference.

根据中的定义创建新的模块对象 def . 这表现得像 PyModule_Create2() 具有 module_api_version 设置为 PYTHON_API_VERSION .

PyObject *PyModule_Create2(PyModuleDef *def, int module_api_version)
Return value: New reference.

根据中的定义创建新的模块对象 def ,假设API版本 module_api_version . 如果该版本与正在运行的解释器的版本不匹配,则 RuntimeWarning 发射。

注解

此函数的大多数用途都应使用 PyModule_Create() 相反,只有当你确定你需要它时才使用它。

在从初始化函数中返回之前,通常使用如下函数填充生成的模块对象 PyModule_AddObjectRef()

多阶段初始化

另一种指定扩展的方法是请求“多阶段初始化”。以这种方式创建的扩展模块的行为更像python模块:初始化在 创作阶段 ,当创建模块对象时, 执行阶段 ,当它被填充时。区别类似于 __new__()__init__() 类的方法。

与使用单相初始化创建的模块不同,这些模块不是单例模块:如果 sys.modules 条目被移除,模块被重新导入,新的模块对象被创建,旧的模块被正常的垃圾收集——就像Python模块一样。默认情况下,从同一定义创建的多个模块应该是独立的:对一个模块的更改不应影响其他模块。这意味着所有状态都应该特定于模块对象(例如使用 PyModule_GetState() 或其内容(如模块的 __dict__ 或使用创建的单个类 PyType_FromSpec()

所有使用多阶段初始化创建的模块都需要支持 sub-interpreters . 确保多个模块是独立的通常足以实现这一点。

要请求多阶段初始化,初始化函数(pyinit_modulename)返回 PyModuleDef 非空实例 m_slots .在归还之前, PyModuleDef 必须使用以下函数初始化实例:

PyObject *PyModuleDef_Init(PyModuleDef *def)
Return value: Borrowed reference.

确保模块定义是正确初始化的Python对象,该对象正确报告其类型和引用计数。

返回 def 铸造成 PyObject*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 . 只要支持设置和获取与导入相关的属性,就可以使用任何类型。然而,只有 PyModule_Type 如果 PyModuleDef 具有非-NULL m_traversem_clearm_free 非零 m_size 或除 Py_mod_create .

Py_mod_exec

指定调用的函数 执行 模块。这相当于执行Python模块的代码:通常,此函数会向模块添加类和常量。函数的签名是:

int exec_module(PyObject *module)

中频倍数 Py_mod_exec 插槽是指定的,它们按照它们在 m_slots 数组。

PEP 489 有关多阶段初始化的详细信息。

低级模块创建功能

当使用多阶段初始化时,在引擎盖下调用以下函数。它们可以直接使用,例如动态创建模块对象时。注意这两者 PyModule_FromDefAndSpecPyModule_ExecDef 必须调用以完全初始化模块。

PyObject *PyModule_FromDefAndSpec(PyModuleDef *def, PyObject *spec)
Return value: New reference.

根据中的定义创建新的模块对象 模块 和模谱 spec . 这表现得像 PyModule_FromDefAndSpec2() 具有 module_api_version 设置为 PYTHON_API_VERSION .

3.5 新版功能.

PyObject *PyModule_FromDefAndSpec2(PyModuleDef *def, PyObject *spec, int module_api_version)
Return value: New reference.

根据中的定义创建新的模块对象 模块 和模谱 spec ,假设API版本 module_api_version . 如果该版本与正在运行的解释器的版本不匹配,则 RuntimeWarning 发射。

注解

此函数的大多数用途都应使用 PyModule_FromDefAndSpec() 相反,只有当你确定你需要它时才使用它。

3.5 新版功能.

int PyModule_ExecDef(PyObject *module, PyModuleDef *def)

处理任何执行槽 (Py_mod_execdef .

3.5 新版功能.

int PyModule_SetDocString(PyObject *module, const char *docstring)

为设置docstring 模块文档字符串 . 此函数在从创建模块时自动调用 PyModuleDef ,使用任一 PyModule_CreatePyModule_FromDefAndSpec .

3.5 新版功能.

int PyModule_AddFunctions(PyObject *module, PyMethodDef *functions)

从添加函数 NULL 结束 功能 数组到 模块 . 参考 PyMethodDef 有关单个条目的详细信息的文档(由于缺少共享的模块名称空间,C中实现的模块级“函数”通常将模块作为第一个参数接收,使它们与Python类上的实例方法类似)。此函数在从创建模块时自动调用 PyModuleDef ,使用任一 PyModule_CreatePyModule_FromDefAndSpec .

3.5 新版功能.

支持功能

模块初始化函数(如果使用单阶段初始化)或从模块执行槽调用的函数(如果使用多阶段初始化),可以使用以下函数帮助初始化模块状态:

int PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value)

将对象添加到 模块 作为 name 。这是一个方便的函数,可以从模块的初始化函数中使用。

成功后,返回 0 。出错时,引发异常并返回 -1

返回 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;
 }

也可以在不显式检查以下条件的情况下编写该示例 objNULL ::

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)

类似于 PyModule_AddObjectRef() ,但会窃取对 价值 成功时(如果它返回 0 )。

新的 PyModule_AddObjectRef() 函数,因为它很容易通过误用 PyModule_AddObject() 功能。

注解

Unlike other functions that steal references, PyModule_AddObject() only decrements the reference count of value on success.

This means that its return value must be checked, and calling code must Py_DECREF() value manually on error.

示例用法:

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;
}

也可以在不显式检查以下条件的情况下编写该示例 objNULL ::

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)

将整数常量添加到 模块 作为 name . 此便利功能可从模块的初始化功能中使用。返回 -1 关于错误, 0 论成功。

int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value)

将字符串常量添加到 模块 作为 name . 此便利功能可从模块的初始化功能中使用。弦 价值 必须是 NULL -终止。返回 -1 关于错误, 0 论成功。

int PyModule_AddIntMacro(PyObject *module, macro)

将int常量添加到 模块 . 名称和值取自 . 例如 PyModule_AddIntMacro(module, AF_INET) 添加int常量 AF_INET 价值 AF_INET模块 . 返回 -1 关于错误, 0 论成功。

int PyModule_AddStringMacro(PyObject *module, macro)

将字符串常量添加到 模块 .

int PyModule_AddType(PyObject *module, PyTypeObject *type)

将类型对象添加到 模块 . 类型对象是通过内部调用 PyType_Ready() . 类型对象的名称取自 tp_name 在点之后。返回 -1 关于错误, 0 论成功。

3.9 新版功能.

模块查找

单阶段初始化创建可以在当前解释器上下文中查找的单例模块。这允许以后仅使用对模块定义的引用来检索模块对象。

这些函数不能在使用多阶段初始化创建的模块上工作,因为可以从单个定义创建多个这样的模块。

PyObject *PyState_FindModule(PyModuleDef *def)
Return value: Borrowed reference.

返回从中创建的模块对象 def 对于当前的解释器。此方法要求模块对象已附加到解释器状态, PyState_AddModule() 事先。如果找不到相应的模块对象或尚未附加到解释器状态,则返回 NULL .

int PyState_AddModule(PyObject *module, PyModuleDef *def)

将传递给函数的模块对象附加到解释器状态。这使得模块对象可以通过 PyState_FindModule() .

仅对使用单相初始化创建的模块有效。

Python调用 PyState_AddModule 导入模块后自动执行,因此不需要(但无害)从模块初始化代码调用它。只有当模块自己的init代码随后调用 PyState_FindModule . 该函数主要用于实现替代的导入机制(通过直接调用它,或者通过引用它的实现来获取所需状态更新的详细信息)。

打电话的人必须拿着电话。

成功时返回0,失败时返回-1。

3.3 新版功能.

int PyState_RemoveModule(PyModuleDef *def)

删除从中创建的模块对象 def 从解释器状态。成功时返回0,失败时返回-1。

打电话的人必须拿着电话。

3.3 新版功能.