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

2024-06-07 04:39:52 发布

您现在位置:Python中文网/ 问答频道 /正文

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

因此,我的想法是通过web检索例如module.py,然后使用__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

Tags: 模块项目inimportnewmysysmicropython
1条回答
网友
1楼 · 发布于 2024-06-07 04:39:52

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

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())

相关问题 更多 >