实现一个模块

这一章节详细讲解如何在 MicroPython 实现一个核心模块。 MicroPython 模块可以是下列之一:

  • 内置模块( Built-in module ):属于 MicroPython 仓库的核心模块。

  • 用户模块( User module ):你自己的仓库或私有代码库中特定的项目的有用的模块。

  • 动态模块( Dynamic module ):可以在运行时部署并导入到你的设备的模块。

在 MicroPython 中,模块可以在下列路径中实现:

  • py/:与 CPython 核心库功能完全相同的核心库。

  • extmod/: CPython 或 MicroPython 特定的模块,它在多个适配端之间共享。

  • ports/<port>/:适配端特定的模块。

备注

这一章节主要描述在 py/ 或核心模块中实现的模块。 关于实现外部模块的详细信息请参阅 在 C 中扩展 MicroPython 。 关于适配端特定的模块的详细信息请参阅 Porting MicroPython

实现一个核心模块

像 CPython 一样, MicroPython 有可以通过 import 语句导入的核心内置模块。 例如,在 内存管理 中讨论的 gc 模块。

>>> import gc
>>> gc.enable()
>>>

MicroPython 还有一些其他内置标准/核心模块,如 ioarray 等。

首先,在 py/ 目录中创建一个 C 代码文件。 在这个例子中,我们假设为系统添加一个新的模块 subsystem ,将代码实现在文件 modsubsystem.c 中:

#include "py/builtin.h"
#include "py/runtime.h"

#if MICROPY_PY_SUBSYSTEM

// info()
STATIC mp_obj_t py_subsystem_info(void) {
    return MP_OBJ_NEW_SMALL_INT(42);
}
MP_DEFINE_CONST_FUN_OBJ_0(subsystem_info_obj, py_subsystem_info);

STATIC const mp_rom_map_elem_t mp_module_subsystem_globals_table[] = {
    { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_subsystem) },
    { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&subsystem_info_obj) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_subsystem_globals, mp_module_subsystem_globals_table);

const mp_obj_module_t mp_module_subsystem = {
    .base = { &mp_type_module },
    .globals = (mp_obj_dict_t *)&mp_module_subsystem_globals,
};

MP_REGISTER_MODULE(MP_QSTR_subsystem, mp_module_subsystem, MICROPY_PY_SUBSYSTEM);

#endif

模块的实现包括所有与模块相关的函数的定义,并在 mp_module_subsystem_globals_table 中将函数添加到模块的全局表中。 它还通过 mp_module_subsystem 创建了模块对象,并通过 MP_REGISTER_MODULE 宏向更广泛的系统注册该模块。

在编译并运行修改过的 MicroPython 之后,模块即可被导入:

>>> import subsystem
>>> subsystem.info()
42
>>>

info() 函数目前只返回一个数字,但本质上可以扩展为任何类型。 举一反三地,还可以为该新模块添加更多的函数。