MicroPython中如何从字符串代码加载模块且无需写入闪存
MicroPython 从RAM动态加载模块的实现方案
MicroPython的module类型为原生封装,不支持用户侧直接实例化,因此无法使用标准Python的imp.new_module或者直接实例化模块类的方式实现RAM加载,可采用以下两种方案替代:
方案1:极简替代(直接替换imp.new_module逻辑)
仅需几行代码即可完全实现你提供的标准Python示例的等价效果:
my_code = 'a = 5' # 自定义空类替代module类型 class RamModule: pass mymodule = RamModule() exec(my_code, mymodule.__dict__) # 调用效果和标准模块完全一致 print(mymodule.a) # 输出5
如果需要模块携带__name__属性,修改类初始化逻辑即可:
class RamModule: def __init__(self, name): self.__name__ = name mymodule = RamModule('mymodule')
方案2:支持全局导入的完整实现
如果需要让RAM加载的模块支持全局import调用,和闪存加载的模块使用体验完全一致,可以将模块实例注册到sys.modules中:
import sys class RamModule: def __init__(self, name): self.__name__ = name def load_ram_module(module_name: str, code: str): # 已加载过的模块直接清空属性复用,避免重复创建 if module_name in sys.modules: mod = sys.modules[module_name] # 清理旧属性 for attr in list(dir(mod)): if not attr.startswith('_'): delattr(mod, attr) else: mod = RamModule(module_name) sys.modules[module_name] = mod # 执行代码填充模块属性 exec(code, mod.__dict__) return mod
使用示例:
# 从网络获取到的代码 my_code = ''' a = 5 def calc(x): return x * a ''' # 加载到RAM load_ram_module('mymodule', my_code) # 后续可以直接用import调用 import mymodule print(mymodule.calc(3)) # 输出15
注意事项
- 不需要使用的RAM模块可以通过
del sys.modules['模块名']删除,配合gc.collect()释放内存 - 代码字符串中如果存在相对导入语句,需要提前替换为绝对导入,否则执行会报错
- 重载模块后,已经导入该模块的旧引用不会自动更新,需要重新导入才能使用新逻辑
内容的提问来源于stack exchange,提问作者frans
相关产品推荐
相关产品推荐

