gpt4 book ai didi

python - 如何从内存中加载已编译的python模块?

转载 作者:太空狗 更新时间:2023-10-29 22:00:13 26 4
gpt4 key购买 nike

我需要从 zip 文件(由 py2exe 压缩构建)中读取所有模块(预编译)到内​​存中,然后将它们全部加载。我知道这可以通过直接从压缩文件加载来完成,但我需要从内存中加载它们。有任何想法吗? (我在 Windows 上使用 python 2.5.2)TIA史蒂夫

最佳答案

这取决于您究竟拥有什么作为“模块(预编译)”。假设它正是 .pyc 文件的内容,例如 ciao.pyc 由以下人员构建:

$ cat>'ciao.py'
def ciao(): return 'Ciao!'
$ python -c'import ciao; print ciao.ciao()'
Ciao!

IOW,这样构建了 ciao.pyc,说你现在做:

$ python
Python 2.5.1 (r251:54863, Feb 6 2009, 19:02:12)
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> b = open('ciao.pyc', 'rb').read()
>>> len(b)
200

你的目标是从那个字节串 b 到一个可导入的模块 ciao。方法如下:

>>> import marshal
>>> c = marshal.loads(b[8:])
>>> c
<code object <module> at 0x65188, file "ciao.py", line 1>

这是从 .pyc 二进制内容中获取代码对象的方法。 编辑:如果你好奇的话,前 8 个字节是一个“魔数(Magic Number)”和一个时间戳——这里不需要(除非你想对它们进行完整性检查并在必要时引发异常,但是似乎超出了问题的范围;marshal.loads 如果检测到损坏的字符串,无论如何都会引发)。

然后:

>>> import types
>>> m = types.ModuleType('ciao')
>>> import sys
>>> sys.modules['ciao'] = m
>>> exec c in m.__dict__

即:创建一个新的模块对象,将其安装在 sys.modules 中,通过在其 __dict__ 中执行代码对象来填充它。 编辑:当且仅当您可能有循环导入时,您执行sys.modules 插入和exec 的顺序很重要——但是,这是 Python 自己的 import 通常使用的顺序,因此最好模仿它(没有特定的缺点)。

您可以通过多种方式“创建一个新的模块对象”(例如,从标准库模块中的函数,如 newimp),但是“调用类型获取一个实例”是目前常见的 Python 方式,从标准库模块 types,这就是我的建议。

现在,终于:

>>> import ciao
>>> ciao.ciao()
'Ciao!'
>>>

...您可以导入模块并使用它的函数、类等。其他 import(和 from)语句将找到模块作为 sys.modules['ciao'],因此您不需要重复这一系列操作(实际上,如果您想要确保模块可从其他地方导入,则您不需要这里最后的 import 语句 - 我'我添加它只是为了证明它有效;-)。

编辑:如果您绝对必须以这种方式从中导入包和模块,而不是像我刚才展示的“普通模块”,那也是可行的,但有点复杂。由于这个答案已经很长了,我希望您可以为此目的坚持使用普通模块来简化您的生活,所以我将回避这部分答案;-)。

另请注意,在“多次从内存中加载同一模块”的情况下,这可能会或可能不会执行您想要的操作(每次都会重建模块;您可能想检查 sys.modules 并跳过所有内容,如果模块已经存在),特别是当这种重复的“从内存加载”发生在多个线程时(需要锁——但是,更好的架构是有一个专门用于执行任务的专用线程,其他模块通过队列)。

最后,没有讨论如何将此功能安装为透明的“导入 Hook ”,它会自动参与 import 语句内部机制本身——这也是可行的,但不是正是您要问的问题,所以在这里,我也希望您可以通过以简单的方式做事来简化您的生活,正如这个答案所概述的那样。

关于python - 如何从内存中加载已编译的python模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1830727/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com