Module Objects

  • PyTypeObject PyModule_Type
    • 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属性设置为* name *的新模块对象。填写模块的name__doc__packageloader属性(除了name以外的所有属性都设置为None);调用方负责提供file属性。

版本 3.3 中的新Function。

在版本 3.4 中更改:packageloader设置为None

  • PyObject * PyModule_New(const char ** name *)
    • 返回值:新参考.

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

返回实现* module 的名称空间的字典对象;该对象与模块对象的dict属性相同。如果 module *不是模块对象(或模块对象的子类型),则引发SystemError并返回NULL

建议扩展使用其他PyModule_*()PyObject_*()函数,而不是直接操作模块的dict

返回* module *的name值。如果模块不提供一个,或者它不是字符串,则引发SystemError并返回NULL

版本 3.3 中的新Function。

  • const char * PyModule_GetName(PyObject ** module *)

  • 无效* PyModule_GetState(PyObject *模块)

    • 返回模块的“状态”,即,指向在模块创建时分配的内存块的指针,即NULL。参见PyModuleDef.m_size
  • PyModuleDef * PyModule_GetDef(PyObject *模块)

    • 返回指向创建模块的PyModuleDef结构的指针,或者返回NULL(如果不是根据定义创建的模块)。
  • PyObject * PyModule_GetFilenameObject(PyObject *模块)

    • 返回值:新参考.

返回使用* module file属性从中加载 module *的文件的名称。如果未定义,或者它不是 unicode 字符串,请加SystemError并返回NULL;否则,返回对 Unicode 对象的引用。

3.2 版中的新Function。

自版本 3.2 起不推荐使用:PyModule_GetFilename()在无法编码的文件名上引发UnicodeEncodeError,请改用PyModule_GetFilenameObject()

初始化 C 模块

模块对象通常是从扩展模块(导出初始化函数的共享库)或嵌入式模块(其中使用PyImport_AppendInittab()添加初始化函数)创建的。有关详情,请参见构建 C 和 C 扩展扩展嵌入式 Python

初始化函数可以将模块定义实例传递给PyModule_Create(),并返回结果模块对象,也可以pass返回定义结构本身来请求“多阶段初始化”。

  • PyModuleDef

    • 模块定义结构,其中包含创建模块对象所需的所有信息。每个模块通常只有一个静态初始化的此类变量。
  • 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值描述的模块级Function表的指针。如果不存在任何Function,则可以为NULL
  • PyModuleDef_Slot* m_slots

    • 用于多阶段初始化的插槽定义数组,以{0, NULL}条目终止。使用单阶段初始化时,* m_slots *必须为NULL

在版本 3.5 中更改:在版本 3.5 之前,此成员始终设置为NULL,并且定义为:

Note

  • traverseproc m_traverse

    • 在遍历模块对象期间调用的遍历函数;如果不需要,则调用NULL。在分配模块状态之前(PyModule_GetState()可能返回 NULL),并且在执行Py_mod_exec函数之前,可以调用此函数。
  • inquiry m_clear

    • 在 GC 清除模块对象期间调用的清除函数;如果不需要,则返回NULL。在分配模块状态之前(PyModule_GetState()可能返回 NULL),并且在执行Py_mod_exec函数之前,可以调用此函数。
  • freefunc m_free

    • 在释放模块对象期间调用的函数,如果不需要,则返回NULL。在分配模块状态之前(PyModule_GetState()可能返回 NULL),并且在执行Py_mod_exec函数之前,可以调用此函数。

Single-phase initialization

模块初始化Function可以直接创建并返回模块对象。这称为“单阶段初始化”,并使用以下两个模块创建Function之一:

给定* def 中的定义,创建一个新的模块对象。行为类似于PyModule_Create2() module_api_version *设置为PYTHON_API_VERSION

  • PyObject * PyModule_Create2(PyModuleDef ** def *,int * module_api_version *)
    • 返回值:新参考.

假设 API 版本* module_api_version ,在 def *中给定定义,创建一个新的模块对象。如果该版本与正在运行的解释器的版本不匹配,则会发出RuntimeWarning

Note

此Function的大多数用法应改为使用PyModule_Create();仅在确定需要时才使用它。

在初始化函数中将其返回之前,通常使用PyModule_AddObject()之类的函数填充生成的模块对象。

Multi-phase initialization

指定 extensions 的另一种方法是请求“多阶段初始化”。以这种方式创建的扩展模块的行为更像 Python 模块:在创建模块对象时,初始化分为* creation phase 和填充时的 execution phase *。区别类似于类的new()init()方法。

与使用单阶段初始化创建的模块不同,这些模块不是单例的:如果删除了 sys.modules 条目并重新导入了模块,则将创建新的模块对象,并且旧模块将接受正常的垃圾回收。 –与 Python 模块一样。默认情况下,根据同一定义创建的多个模块应该是独立的:对一个模块的更改不会影响其他模块。这意味着所有状态应特定于模块对象(例如,使用PyModule_GetState())或其内容(例如模块的__dict__或使用PyType_FromSpec()创建的单个类)。

使用多阶段初始化创建的所有模块均应支持sub-interpreters。确保多个模块独立通常足以实现此目的。

要请求多阶段初始化,初始化函数(PyInit_modulename)返回带有非空m_slotsPyModuleDef实例。在返回PyModuleDef实例之前,必须使用以下函数对其进行初始化:

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

返回* def *强制转换为PyObject*NULL(如果发生错误)。

3.5 版中的新Function。

模块定义的* m_slots *成员必须指向PyModuleDef_Slot结构的数组:

  • PyModuleDef_Slot

      • int slot
      • 从下面说明的可用值中选择的插槽 ID。
  • 无效* value

    • 插槽的值,其含义取决于插槽 ID。

3.5 版中的新Function。

  • m_slots *数组必须由 ID 为 0 的插槽终止。

可用的插槽类型为:

  • Py_mod_create

    • 指定一个调用以创建模块对象本身的函数。该插槽的* value *指针必须指向签名的Function:
  • PyObject * create_module(PyObject *spec PyModuleDef def *)

该函数接收 PEP 451中定义的ModuleSpec实例和模块定义。它应该返回一个新的模块对象,或者设置一个错误并返回NULL

此Function应保持最小。特别是,它不应调用任意 Python 代码,因为try再次导入同一模块可能会导致无限循环。

一个模块定义中可能未指定多个Py_mod_create插槽。

如果未指定Py_mod_create,则导入机制将使用PyModule_New()创建普通模块对象。该名称取自* spec *而非定义,以允许扩展模块动态调整至其在模块层次结构中的位置,并pass符号链接以不同的名称导入,所有这些都共享一个模块定义。

不需要返回的对象为PyModule_Type的实例。可以使用任何类型,只要它支持设置和获取与导入相关的属性即可。但是,如果PyModuleDef不具有NULL m_traversem_clearm_free,则只能返回PyModule_Type个实例;非零m_size;或Py_mod_create以外的插槽。

  • Py_mod_exec

    • 指定被调用以“执行”模块的函数。这等效于执行 Python 模块的代码:通常,此函数向该模块添加类和常量。该函数的签名是:
  • int exec_module(PyObject * * module *)

如果指定了多个Py_mod_exec插槽,则会按照它们在* m_slots *数组中出现的 Sequences 进行处理。

有关多阶段初始化的更多详细信息,请参见 PEP 489

低级模块创建Function

使用多阶段初始化时,将在后台调用以下Function。它们可以直接使用,例如在动态创建模块对象时。请注意,必须同时调用PyModule_FromDefAndSpecPyModule_ExecDef才能完全初始化模块。

给定* module *中的定义和 ModuleSpec * spec 中的定义,创建一个新的模块对象。行为类似于PyModule_FromDefAndSpec2() module_api_version *设置为PYTHON_API_VERSION

3.5 版中的新Function。

假定 API 版本* module_api_version ,在 module *和 ModuleSpec * spec *中给定定义,创建一个新的模块对象。如果该版本与正在运行的解释器的版本不匹配,则会发出RuntimeWarning

Note

此Function的大多数用法应改为使用PyModule_FromDefAndSpec();仅在确定需要时才使用它。

3.5 版中的新Function。

3.5 版中的新Function。

  • int PyModule_SetDocString(PyObject *module ,const char docstring *)
    • 将* module 的 docstring 设置为 docstring *。使用PyModule_CreatePyModule_FromDefAndSpecPyModuleDef创建模块时,会自动调用此函数。

3.5 版中的新Function。

  • 整数PyModule_AddFunctions(PyObject 模块PyMethodDef* Function*)
    • NULL终止的* functions 数组中的函数添加到 module *中。有关各个条目的详细信息,请参阅PyMethodDef文档(由于缺少共享的模块名称空间,C 语言中实现的模块级“Function”通常将模块作为其第一个参数,使其类似于 Python 类的实例方法)。使用PyModule_CreatePyModule_FromDefAndSpecPyModuleDef创建模块时,将自动调用此函数。

3.5 版中的新Function。

Support functions

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

  • int PyModule_AddObject(PyObject *module ,const char name *,PyObject ** value *)
    • 将一个对象作为* name 添加到 module 。这是一个便捷Function,可以从模块的初始化Function中使用。成功时会窃取对 value *的引用。错误返回-1,成功返回0

Note

与其他窃取引用的函数不同,PyModule_AddObject()仅在成功**时递减* value *的引用计数。

这意味着必须检查其返回值,并且调用代码必须在出错时手动Py_DECREF() * value *。用法示例:

Py_INCREF(spam);
if (PyModule_AddObject(module, "spam", spam) < 0) {
Py_DECREF(module);
Py_DECREF(spam);
return NULL;
}
  • int PyModule_AddIntConstant(PyObject *module ,const char name *,long * value *)

    • 向* module 添加一个整数常量作为 name *。可以从模块的初始化Function中使用此便利Function。错误返回-1,成功返回0
  • int PyModule_AddStringConstant(PyObject *module ,const char name *,const char ** value *)

    • 将字符串常量作为* name 添加到 module 。可以从模块的初始化Function中使用此便利Function。字符串 value *必须以NULL终止。错误返回-1,成功返回0
  • int PyModule_AddIntMacro(PyObject ** module *,宏)

    • 向* module 添加一个 int 常量。名称和值取自 macro 。例如PyModule_AddIntMacro(module, AF_INET) AF_INET 的 int 常量 AF_INET 添加到 module *。错误返回-1,成功返回0
  • int PyModule_AddStringMacro(PyObject ** module *,宏)

    • 向* module *添加一个字符串常量。

Module lookup

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

这些Function不适用于使用多阶段初始化创建的模块,因为可以从单个定义中创建多个此类模块。

返回从* def *为当前解释器创建的模块对象。此方法要求模块对象已预先passPyState_AddModule()附加到解释器状态。如果未找到相应的模块对象或尚未将其附加到解释器状态,则返回NULL

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

导入模块后,Python 会自动调用PyState_AddModule,因此无需(但无害)从模块初始化代码中调用它。仅当模块自己的初始化代码随后调用PyState_FindModule时才需要显式调用。该Function主要用于实现替代的导入机制(pass直接调用它,或pass参考其实现以获取所需状态更新的详细信息)。

成功返回 0,失败则返回-1.

版本 3.3 中的新Function。

  • int PyState_RemoveModule(PyModuleDef ** def *)
    • 从解释器状态中删除从* def *创建的模块对象。成功返回 0,失败则返回-1.

版本 3.3 中的新Function。