实现一个模块

本章详细介绍如何在 MicroPython 中实现一个核心模块。MicroPython 模块可以是以下几种之一:

  • 内置模块:作为 MicroPython 仓库一部分的通用模块。

  • 用户模块:对你的特定项目有用、由你在自己的仓库或私有代码库中维护的模块。

  • 动态模块:可在运行时部署并导入到你设备上的模块。

MicroPython 中的模块可以在以下某个位置实现:

  • py/:镜像 CPython 核心功能的核心库。

  • extmod/:在多个移植版本之间共享的、特定于 CPython 或 MicroPython 的模块。

  • ports/<port>/:特定于移植版本的模块。

备注

本章描述在 py/ 中实现的模块或核心模块。有关实现外部模块的详情,请参阅 用 C 扩展 MicroPython。有关特定于移植版本的模块的详情,请参阅 移植 MicroPython

实现一个核心模块

与 CPython 一样,MicroPython 拥有可通过 import 语句访问的核心内置模块。一个例子是 内存管理 中讨论的 gc 模块。

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

MicroPython 还有其他几个内置的标准/核心模块,如 ioarray 等。添加一个新的核心模块涉及多处修改。

首先,在 py/ 目录中创建 C 文件。在本示例中,我们在文件 modsubsystem.c 中添加一个假想的新模块 subsystem

#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);

#endif

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

在构建并运行修改后的 MicroPython 之后,现在应该可以导入该模块了:

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

我们的 info() 函数目前仅返回单个数字,但可以扩展为执行任何操作。同样,还可以向这个新模块添加更多函数。