如何在Python 3.11中从字节序列加载模块而不保存到文件?
我的加载器从服务器接收部分程序,格式是 .pyc
文件(这些文件并没有保存在客户端的文件系统中,而是以字节序列的形式存储在一个变量里)。
我需要从这个字节序列创建一个模块,而不想创建任何文件。
我找到了一种从字符串创建模块的方法:
spec = importlib.util.spec_from_loader("modulename", loader=None) # creating spec
module = importlib.util.module_from_spec(spec) # creating module
exec(source, module.__dict__) # executing module
# so that we can import it in other program files
sys.modules[name] = module
globals()[name] = module
但是在我的情况下,这个方法不管用。
这个模块最开始是通过 py_compile.compile("sorcefile.py", "destfile.pyc")
创建的。对于一个类似的问题的回答(如何从内存加载编译过的Python模块?)建议使用 marshal.loads(bytes[8:])
,确实,当我查看 py_compile.compile
函数的源代码时(https://svn.python.org/projects/python/trunk/Lib/py_compile.py),我发现它使用了 marshal.dump()
。不过,据我了解,这段代码已经过时了,因为在我使用的Python版本(3.11)中查看这个函数的源代码时(https://github.com/python/cpython/blob/3.11/Lib/py_compile.py),我发现它不再使用marshal了。
这就解释了为什么在以下情况下会出现错误:
import marshal
import py_compile
py_compile.compile("source.py", "compiled.pyc")
with open("compiled.pyc", "rb") as f:
module_bytes = f.read()
module = marshal.loads(module_bytes[8:])
输出:
Traceback (most recent call last):
File "C:\test.py", line 9, in <module>
module = marshal.loads(module_bytes[8:])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: bad marshal data (unknown type code)
(在这个情况下,pyc文件只是为了模拟从服务器接收到的数据。)
那么,在Python 3.11中,是否有可能从字节序列创建模块,而不创建文件(就像用 "字符串" 方法那样)呢?
0 个回答
暂无回答