模块对象
********

PyTypeObject PyModule_Type

   这个 C 类型实例 "PyTypeObject" 用来表示Python中的模块类型。在
   Python 程序中该实例被暴露为 "types.ModuleType"。

int PyModule_Check(PyObject *p)

   当 *p* 为模块类型的对象，或是模块子类型的对象时返回真值。该函数永远
   有返回值。

int PyModule_CheckExact(PyObject *p)

   当 *p* 为模块类型的对象且不是 "PyModule_Type" 的子类型的对象时返回
   真值。该函数永远有返回值。

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

   返回新的模块对象，其属性 "__name__"  为 *name* 。模块的如下属性
   "__name__", "__doc__", "__package__", and "__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.*

   返回实现 *module* 的命名空间的字典对象；此对象与模块对象的
   "__dict__" 属性相同。 如果 *module* 不是一个模块对象（或模块对象的
   子类型），则会引发 "SystemError" 并返回 "NULL"。

   建议扩展使用其他 "PyModule_*()" and "PyObject_*()" 函数而不是直接操
   纵模块的 "__dict__"。

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

   返回 *module* 的 "__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.*

   返回使用 *module* 的 "__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()" 传入一个模块定义实例，并返回结果
模块对象，或者通过返回定义结构体本身来请求“多阶段初始化”。

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" 描述。如果模块没有函
      数，可以为 "NULL"。

   PyModuleDef_Slot* m_slots

      由针对多阶段初始化的槽位定义组成的数组，以一个 "{0, NULL}" 条目
      结束。 当使用单阶段初始化时，*m_slots* 必须为 "NULL"。

      在 3.5 版更改: 在 3.5 版之前，此成员总是被设为 "NULL"，并被定义
      为:

         inquiry m_reload

   traverseproc m_traverse

      在模块对象的垃圾回收遍历期间所调用的遍历函数，如果不需要则为
      "NULL"。

      如果模块状态已被请求但尚未被分配，则不会调用此函数。例如在模块刚
      刚创建完成之后、被执行之前（"Py_mod_exec" 函数）时的情况。更准确
      地说，如果 "m_size" 大于0，并且模块状态（由
      "PyModule_GetState()" 返回）为 "NULL"，则不会调用此函数。

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

   inquiry m_clear

      在模块对象的垃圾回收清理期间所调用的清理函数，如果不需要则为
      "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 版更改: 在模块状态被分配之前不再调用。


单阶段初始化
------------

模块初始化函数可以直接创建并返回模块对象，称为“单阶段初始化”，使用以下
两个模块创建函数中的一个：

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

   创建一个新的模块对象，在参数 *def* 中给出定义。它等同于将参数
   *module_api_version* 设置为 "PYTHON_API_VERSION" 的
   "PyModule_Create2()" 函数。

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

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

   注解:

     大多数时候应该使用 "PyModule_Create()" 代替使用此函数，除非你确定
     需要使用它。

Before it is returned from in the initialization function, the
resulting module object is typically populated using functions like
"PyModule_AddObject()".


多阶段初始化
------------

另一种指定扩展的方式是“多阶段初始化”。以这种方式创建的扩展模块的行为更
类似 Python 模块：初始化分成两个阶段，*创建阶段* 创建模块对象，*执行阶
段* 填充模块对象。它们的区别类似类的 "__new__()" 和 "__init__()" 方法
。

与使用单阶段初始化创建的模块不同，这些模块不是单例：如果 *sys.modules*
被移除、模块被重新导入，将会创建一个新的模块对象，旧模块将进入常规的垃
圾回收——就像 Python 模块那样。默认情况下，根据同一个定义创建的多个模块
应该是相互独立的：修改其中之一不应该影响其它模块。这意味着所有状态都应
该特定于模块对象（例如使用 "PyModule_GetState()"），或是它的内容（例如
模块的 "__dict__" 属性，或是使用 "PyType_FromSpec()" 创建的独立的类）
。

所有使用多阶段初始化创建的模块都应该支持 子解释器。保证多个模块之间相
互独立，通常就可以实现这一点。

要请求多阶段初始化，初始化函数 (PyInit_modulename) 返回一个包含非空的
"m_slots" 属性的 "PyModuleDef" 实例。在它被返回之前，这个
"PyModuleDef" 实例必须先使用以下函数初始化：

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

   确保模块定义是一个正确初始化的Python对象，拥有正确的类型和引用计数
   。

   返回转换为 "PyObject*" 的 *def* ，如果发生错误，则返回 "NULL"。

   3.5 新版功能.

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

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" 的实例。 任何类型均可使用，
   只要它支持设置和获取导入相关的属性。 但是，如果 "PyModuleDef" 具有
   非 "NULL" 的 "m_traverse", "m_clear", "m_free"；非零的 "m_size"；或
   者 "Py_mod_create" 以外的槽位则只能返回 "PyModule_Type" 的实例。

Py_mod_exec

   指定一个供调用以 *执行* 模块的函数。 这造价于执行一个 Python 模块的
   代码：通常，此函数会向模块添加类和常量。 此函数的签名为:

   int exec_module(PyObject* module)

   如果指定了多个 "Py_mod_exec" 槽位，将按照它们在*m_slots*数组中出现
   的顺序进行处理。

有关多阶段初始化的更多细节，请参阅PEP:*489*


底层模块创建函数
----------------

当使用多阶段初始化时，将会调用以下函数。例如，在动态创建模块对象的时候
，可以直接使用它们。注意，必须调用 "PyModule_FromDefAndSpec" 和
"PyModule_ExecDef" 来完整地初始化一个模块。

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

   创建一个新的模块对象，在参数 *module* 和 *spec* 中给出定义。它等同
   于将参数 *module_api_version* 设置为 "PYTHON_API_VERSION" 的
   "PyModule_FromDefAndSpec2()" 函数。

   3.5 新版功能.

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

   创建一个新的模块对象，在参数 *module* 和 *spec* 中给出定义，设置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)

   将*module*的文档字符串设置为*docstring*。当使用 "PyModule_Create"
   或 "PyModule_FromDefAndSpec" 从 "PyModuleDef" 创建模块时，会自动调
   用此函数。

   3.5 新版功能.

int PyModule_AddFunctions(PyObject *module, PyMethodDef *functions)

   将以 "NULL" 结尾的*functions*数组中的函数添加到*module*模块中。有关
   单个条目的更多细节，请参与 "PyMethodDef" 文档（由于缺少共享的模块命
   名空间，在C中实现的模块级“函数”通常将模块作为它的第一个参数，与
   Python类的实例方法类似）。当使用 "PyModule_Create" 或
   "PyModule_FromDefAndSpec" 从 "PyModuleDef" 创建模块时，会自动调用此
   函数。

   3.5 新版功能.


支持函数
--------

模块初始化函数（单阶段初始化）或通过模块的执行槽位调用的函数（多阶段初
始化），可以使用以下函数，来帮助初始化模块的状态：

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

   Add an object to *module* as *name*.  This is a convenience
   function which can be used from the module's initialization
   function.  This steals a reference to *value* on success. Return
   "-1" on error, "0" on success.

   注解:

     和其它窃取引用的函数不同，"PyModule_AddObject()" 只在**成功**时减
     少*value*的引用计数。This means that its return value must be
     checked, and calling code must "Py_DECREF()" *value* manually on
     error. Example usage:

        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)

   将一个名称为*name*的整型常量添加到*module*模块中。这个方便的函数可
   以在模块的初始化函数中使用。如果发生错误，返回 "-1"，成功返回 "0"。

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

   将一个名称为*name*的字符串常量添加到*module*模块中。这个方便的函数
   可以在模块的初始化函数中使用。字符串*value*必须以 "NULL" 结尾。如果
   发生错误，返回 "-1" ，成功返回 "0" 。

int PyModule_AddIntMacro(PyObject *module, macro)

   将一个整型常量添加到*module*模块中。名称和值取自*macro*参数。例如，
   "PyModule_AddIntMacro(module, AF_INET)" 将值为*AF_INET*的整型常量
   *AF_INET*添加到*module*模块中。如果发生错误，返回 "-1" ，成功返回
   "0" 。

int PyModule_AddStringMacro(PyObject *module, macro)

   将一个字符串常量添加到*module*模块中。

int PyModule_AddType(PyObject *module, PyTypeObject *type)

   将一个类型对象添加到 *module* 模块中。类型对象通过在函数内部调用
   "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"，因此从模块初
   始化代码中调用它是没有必要的（但也没有害处）。 显式的调用仅在模块自
   己的初始化代码后继调用了 "PyState_FindModule" 的情况下才是必要的。
   此函数主要是为了实现替代导入机制（或是通过直接调用它，或是通过引用
   它的实现来获取所需的状态更新详情）。

   调用时必须携带GIL。

   成功是返回 0 或者失败时返回 -1。

   3.3 新版功能.

int PyState_RemoveModule(PyModuleDef *def)

   从解释器状态中移除由 *def* 创建的模块对象。 成功时返回 0，者失败时
   返回 -1。

   调用时必须携带GIL。

   3.3 新版功能.
