In a ESP32/MicroPython based project I want to (re)load modules from RAM without having to write them to the flash-based filesystem first. (this is both time consuming and wearing off the flash memory)
So my idea was to retrieve e.g. module.py
via web and then turn it into an actual module by using __import__
, exec()
and so on. But I don't know how.
Actually what I need is quite similar to this: How to load a module from code in a string?
In MicroPython there are no imp
or importlib
or even types.ModuleType
module but at least you have __import__
.
Is there a way to implement
my_code = 'a = 5'
mymodule = imp.new_module('mymodule')
exec(my_code, mymodule.__dict__)
Without imp.new_module
?
I tried sys.__class__('mymodule')
in order smuggle the module type out of an existing module but I get
>>> mymodule = sys.__class__('mymodule')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't create 'module' instances
I don't know if this is feasible for you, but an alternative approach might be to create a filesystem in ram, copy the string to that, then use conventional import statements.
The MicroPython reference says "filesystems can also use external flash, RAM,...", and "MicroPython implements a Unix-like Virtual File System (VFS) layer", and goes on to provide the code to implement a simple block device in 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
You create and mount a filesystem simply:
import os
bdev = RAMBlockDev(512, 50)
os.VfsFat.mkfs(bdev)
os.mount(bdev, '/ramdisk')
and then use it simply:
with open('/ramdisk/hello.txt', 'w') as f:
f.write('Hello world')
print(open('/ramdisk/hello.txt').read())