Implementar un módulo

Este capítulo detalla cómo implementar un módulo principal en MicroPython. Los módulos de MicroPython pueden ser de uno de los siguientes tipos:

  • Módulo integrado: un módulo general que forma parte del repositorio de MicroPython.

  • Módulo de usuario: un módulo útil para tu proyecto concreto que mantienes en tu propio repositorio o en una base de código privada.

  • Módulo dinámico: un módulo que puede desplegarse e importarse en tiempo de ejecución en tu dispositivo.

Un módulo en MicroPython puede implementarse en una de las siguientes ubicaciones:

  • py/: una biblioteca principal que refleja la funcionalidad principal de CPython.

  • extmod/: un módulo específico de CPython o MicroPython que se comparte entre múltiples ports.

  • ports/<port>/: un módulo específico de un port.

Nota

Este capítulo describe los módulos implementados en py/, es decir, los módulos principales. Consulta Extender MicroPython en C para más detalles sobre cómo implementar un módulo externo. Para más detalles sobre los módulos específicos de un port, consulta Portar MicroPython.

Implementar un módulo principal

Al igual que CPython, MicroPython tiene módulos integrados principales a los que se puede acceder mediante sentencias import. Un ejemplo es el módulo gc tratado en Gestión de memoria.

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

MicroPython tiene varios otros módulos estándar/principales integrados como io, array, etc. Añadir un nuevo módulo principal implica varias modificaciones.

Primero, crea el archivo C en el directorio py/. En este ejemplo añadimos un hipotético módulo nuevo subsystem en el archivo 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);

#endif

La implementación incluye una definición de todas las funciones relacionadas con el módulo y añade las funciones a la tabla global del módulo en mp_module_subsystem_globals_table. También crea el objeto del módulo con mp_module_subsystem. El módulo se registra luego en el sistema general mediante la macro MP_REGISTER_MODULE.

Tras compilar y ejecutar el MicroPython modificado, el módulo ya debería poder importarse:

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

Nuestra función info() actualmente solo devuelve un único número, pero puede ampliarse para hacer cualquier cosa. De forma similar, se pueden añadir más funciones a este nuevo módulo.