Module Objects

PyTypeObject PyModule_Type

此实例PyTypeObject表示Python模块类型。这将暴露给Python程序,如types.ModuleType

int PyModule_Check(PyObject *p)

如果p是模块对象或模块对象的子类型,则返回true。

int PyModule_CheckExact(PyObject *p)

如果p是模块对象,而不是PyModule_Type的子类型,则返回true。

PyObject* PyModule_NewObject(PyObject *name)

返回一个新的模块对象,其中__name__属性设置为nameThe module’s __name__, __doc__, __package__, and __loader__ attributes are filled in (all but __name__ are set to None); the caller is responsible for providing a __file__ attribute.

版本3.3中的新功能。

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

PyObject* PyModule_New(const char *name)
返回值:新引用。

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

PyObject* PyModule_GetDict(PyObject *module)
返回值:借用引用。

返回实现module的命名空间的字典对象;此对象与模块对象的__dict__属性相同。此函数永远不会失败。建议扩展使用其他PyModule_*()PyObject_*()函数,而不是直接操作模块的__dict__

PyObject* PyModule_GetNameObject(PyObject *module)

返回模块__name__值。如果模块不提供一个,或者不是字符串,则会引发SystemError并返回NULL

版本3.3中的新功能。

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)

使用模块 tl>的__file__属性返回加载了模块的文件的名称。如果没有定义,或者它不是unicode字符串,则引发SystemError并返回NULL;否则返回对Unicode对象的引用。

版本3.2中的新功能。

char* PyModule_GetFilename(PyObject *module)

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

自从版本3.2之后已弃用: PyModule_GetFilename()引发UnicodeEncodeError在不可编辑的文件名上,使用PyModule_GetFilenameObject()

Initializing C modules

模块对象通常是从扩展模块(导出初始化函数的共享库)或编译模块(其中使用PyImport_AppendInittab()添加初始化函数)创建的。有关详细信息,请参见Building C and C++ ExtensionsExtending Embedded Python

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

PyModuleDef

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

PyModuleDef_Base m_base

始终将此成员初始化为PyModuleDef_HEAD_INIT

char* m_name

新模块的名称。

char* m_doc

Docstring模块;通常使用用PyDoc_STRVAR()创建的docstring变量。

Py_ssize_t m_size

模块状态可以保存在可以用PyModule_GetState()检索的每个模块存储器区域中,而不是在静态全局变量中。这使得模块安全用于多个子解释器。

在调用m_free函数(如果存在)之后,在模块创建时基于m_size分配此内存区域,并在释放模块对象时释放该内存区域。

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

inquiry m_clear

在GC清除模块对象期间调用的清除函数,或者如果不需要,则NULL

freefunc m_free

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

Single-phase initialization

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

PyObject* PyModule_Create(PyModuleDef *def)

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

PyObject* PyModule_Create2(PyModuleDef *def, int module_api_version)

Create a new module object, given the definition in def, assuming the API version module_api_version. 如果该版本与正在运行的解释器的版本不匹配,则会发出RuntimeWarning

注意

此函数的大多数用法应该是使用PyModule_Create();只有使用这个,如果你确定你需要它。

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

Multi-phase initialization

指定扩展的另一种方法是请求“多阶段初始化”。以此方式创建的扩展模块更像Python模块:初始化在创建模块对象时的创建阶段和填充的执行阶段之间分割。区别类似于类的__new__()__init__()方法。

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

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

为了请求多阶段初始化,初始化函数(PyInit_modulename)返回具有非空的m_slotsPyModuleDef实例。在返回之前,必须使用以下函数初始化PyModuleDef实例:

PyObject* PyModuleDef_Init(PyModuleDef *def)

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

如果发生错误,则返回def cast到PyObject*NULL

版本3.5中的新功能。

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

PyModuleDef_Slot
int slot

插槽ID,从下面介绍的可用值中选择。

void* value

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

版本3.5中的新功能。

m_slots数组必须由id为0的插槽终止。

可用的插槽类型有:

Py_mod_create

指定被调用以创建模块对象本身的函数。此槽的指针必须指向声明的函数:

PyObject* create_module(PyObject *spec, PyModuleDef *def)

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

这个函数应该保持最小。特别是,它不应该调用任意Python代码,因为尝试再次导入相同的模块可能会导致无限循环。

在一个模块定义中可能不能指定多个Py_mod_create槽。

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

没有要求返回的对象是PyModule_Type的实例。可以使用任何类型,只要它支持设置和获取导入相关的属性。However, only PyModule_Type instances may be returned if the PyModuleDef has non-NULL m_methods, m_traverse, m_clear, m_free; non-zero m_size; or slots other than Py_mod_create.

Py_mod_exec

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

int exec_module(PyObject* module)

如果指定了多个Py_mod_exec插槽,则按照它们在m_slots数组中出现的顺序处理它们。

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

Low-level module creation functions

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

PyObject * PyModule_FromDefAndSpec(PyModuleDef *def, PyObject *spec)

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

版本3.5中的新功能。

PyObject * PyModule_FromDefAndSpec2(PyModuleDef *def, PyObject *spec, int module_api_version)

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

注意

此函数的大多数用法应该是使用PyModule_FromDefAndSpec();只有使用这个,如果你确定你需要它。

版本3.5中的新功能。

int PyModule_ExecDef(PyObject *module, PyModuleDef *def)

处理在def中给出的任何执行槽(Py_mod_exec)。

版本3.5中的新功能。

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

模块的docstring设置为docstring使用PyModule_CreatePyModule_FromDefAndSpecPyModuleDef创建模块时,将自动调用此函数。

版本3.5中的新功能。

int PyModule_AddFunctions(PyObject *module, PyMethodDef *functions)

NULL终止的函数数组中的函数添加到模块有关单个条目的详细信息,请参阅PyMethodDef文档(由于缺少共享模块命名空间,在C中实现的模块级“函数”通常会接收模块作为它们的第一个参数,使其类似于实例Python类的方法)。使用PyModule_CreatePyModule_FromDefAndSpecPyModuleDef创建模块时,将自动调用此函数。

版本3.5中的新功能。

Support functions

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

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

模块添加对象name这是一个方便的功能,可以从模块的初始化函数中使用。这会窃取对的引用。成功时返回-1错误,0

int PyModule_AddIntConstant(PyObject *module, const char *name, long value)

模块添加一个整数常量为name可以从模块的初始化函数使用此方便功能。成功时返回-1错误,0

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

模块添加字符串常量为名称可以从模块的初始化函数使用此方便功能。字符串必须为NULL - 终止。返回-1表示发生错误,0表示成功。

int PyModule_AddIntMacro(PyObject *module, macro)

模块添加int常量。名称和值取自For example PyModule_AddIntMacro(module, AF_INET) adds the int constant AF_INET with the value of AF_INET to module. 成功时返回-1错误,0

int PyModule_AddStringMacro(PyObject *module, macro)

模块添加字符串常量。

Module lookup

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

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

PyObject* PyState_FindModule(PyModuleDef *def)

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

int PyState_AddModule(PyObject *module, PyModuleDef *def)

将传递给函数的模块对象附加到解释器状态。这允许通过PyState_FindModule()访问模块对象。

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

版本3.3中的新功能。

int PyState_RemoveModule(PyModuleDef *def)

从解释器状态删除从def创建的模块对象。

版本3.3中的新功能。