在 MicroPython 中,如何从字符串中加载模块

Posted

技术标签:

【中文标题】在 MicroPython 中,如何从字符串中加载模块【英文标题】:In MicroPython how do I load a module from a string 【发布时间】:2021-11-08 05:01:26 【问题描述】:

在基于 ESP32/MicroPython 的项目中,我想从 RAM(重新)加载模块,而不必先将它们写入基于闪存的文件系统。 (这既费时又消耗闪存)

所以我的想法是检索例如module.py通过web,然后使用__import__exec()等将其转换为实际模块。但我不知道怎么做。

其实我需要的和这个差不多:How to load a module from code in a string?

在 MicroPython 中没有 impimportlib 甚至 types.ModuleType 模块,但至少你有 __import__

有没有办法实现

my_code = 'a = 5'
mymodule = imp.new_module('mymodule')
exec(my_code, mymodule.__dict__)

没有imp.new_module

我尝试使用sys.__class__('mymodule') 将模块类型从现有模块中偷运出来,但我得到了

>>> mymodule = sys.__class__('mymodule')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't create 'module' instances

【问题讨论】:

如果您只需要命名空间/.__dict__,那么为什么不能只使用虚拟类而不是ModuleType 【参考方案1】:

我不知道这对您是否可行,但另一种方法可能是在 ram 中创建一个文件系统,将字符串复制到该文件系统,然后使用传统的 import 语句。

MicroPython reference 表示“文件系统也可以使用外部闪存、RAM 等”,以及“MicroPython 实现了类似 Unix 的虚拟文件系统 (VFS) 层”,以及 继续提供在 RAM 中实现简单块设备的代码:

class RAMBlockDev:
    def __init__(self, block_size, num_blocks):
        self.block_size = block_size
        self.data = bytearray(block_size * num_blocks)

    def readblocks(self, block_num, buf):
        for i in range(len(buf)):
            buf[i] = self.data[block_num * self.block_size + i]

    def writeblocks(self, block_num, buf):
        for i in range(len(buf)):
            self.data[block_num * self.block_size + i] = buf[i]

    def ioctl(self, op, arg):
        if op == 4: # get number of blocks
            return len(self.data) // self.block_size
        if op == 5: # get block size
            return self.block_size

您只需创建和挂载文件系统:

import os
bdev = RAMBlockDev(512, 50)
os.VfsFat.mkfs(bdev)
os.mount(bdev, '/ramdisk')

然后简单地使用它:

with open('/ramdisk/hello.txt', 'w') as f:
    f.write('Hello world')
print(open('/ramdisk/hello.txt').read())

【讨论】:

这实际上是我现在正在做的事情——我希望有一些轻巧的旅行方式,但看起来这是节省闪存的方式。我想知道为什么 MicroPython 一直从头开始删除创建模块的所有方法。无论如何我希望这不是 the 最终答案,但我给你+1,因为它有效。如果没有好的方法,我将把它作为答案(我必须先重新提出我的问题:))

以上是关于在 MicroPython 中,如何从字符串中加载模块的主要内容,如果未能解决你的问题,请参考以下文章

如何从打印的数据帧字符串中加载数据帧? [复制]

如何将非通用排序列表保存到文件中,以便可以从文件中加载该排序列表?

如何在运行时生成的 QML 中加载图像(jpg)

如何在反应中从文件中加载数据?

如何从打包在war文件中的jar文件中加载资源? [复制]

ScrollView:如何从文档中加载图像