博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python从内存中使用编译后的模块
阅读量:5069 次
发布时间:2019-06-12

本文共 1940 字,大约阅读时间需要 6 分钟。

  在Windows编程的时候,有些时候,我们经常会要使用一些非常规的方法,比如说从内存中加载DLL,然后使用DLL中的函数。于是就思索在用Python的时候是否能够将几个编译好的Pyc合并成一个,然后使用动态的读取这个文件,然后根据标记进行划分,获得不同的模块的pyc内容,然后动态作为一个新的模块引用到我们的程序中去,这就涉及到一个问题,如何将一个pyc整到内存,然后从内存中获取变成一个新模块进行引入处理。之后找了一些资料之后,发现一种方法,就是通过PyCodeObject这个代码对象来进行处理,也就是用compile编译之后的内容,然后读取形成codeobject对象,然后用types.ModuleType建立一个新的模块,然后将这个新模块加入到sys.modules字典中去,之后在这这个新建的模块环境中执行前面读取的codeObject对象,那么久可以使用这个新的导入模块了,方式如下:

#代码如下:PycContext = open('test.pyo', 'rb').read()import marshal#可以查看PyCodeObject数据结构前面8个位是一个4字节MagicNum和4字节的时间戳,所以从第八位开始PyCodeObject = marshal.loads(b[8:])import types#建立一个名字叫testSimple的新模块newModule = types.ModuleType('testSimple')import syssys.modules['testSimple'] = newModule#这个时候已经可以用import testSimple了#但是运行时候会发现,这个新模块什么功能函数都没有,因为还没有和#上面的PyCodeObject关联起来,此时需要关联#就是使用exec在本模块环境执行一次,则可exec c in newModule.__dict__#这样,上面的codeObject和新模块就关联起来了,然后就可以使用里面的函数了

另外记录一个外国的资料代码如下

def load_compiled_from_memory(name, filename, data, ispackage=False):    if data[:4]!=imp.get_magic():        raise ImportError('Bad magic number in %s' % filename)    # Ignore timestamp in data[4:8]    code = marshal.loads(data[8:])    imp.acquire_lock() # Required in threaded applications    try:        mod = imp.new_module(name)        sys.modules[name] = mod # To handle circular and submodule imports                                 # it should come before exec.        try:            mod.__file__ = filename # Is not so important.            # For package you have to set mod.__path__ here.             # Here I handle simple cases only.            if ispackage:                mod.__path__ = [name.replace('.', '/')]            exec code in mod.__dict__        except:            del sys.modules[name]            raise    finally:        imp.release_lock()    return mod

另外需要说明一下的是,使用Python import自动生成的编译后的文件一般都带有魔数和时间戳,也就是说读取codeObject的时候需要移动8位,但是有些用Python的API生成的不一定带有这个魔数和时间戳的,那么这个时候就不用移位,而直接读取生成codeobject

 

转载于:https://www.cnblogs.com/DxSoft/p/3667290.html

你可能感兴趣的文章
poj1981 Circle and Points 单位圆覆盖问题
查看>>
POP的Stroke动画
查看>>
线程同步机制初识 【转载】
查看>>
Oracle 游标使用全解
查看>>
SQL语句在查询分析器中可以执行,代码中不能执行
查看>>
yii 1.x 添加 rules 验证url数组
查看>>
html+css 布局篇
查看>>
银行排队问题(详解队列)
查看>>
序列化和反序列化(1)---[Serializable]
查看>>
SQL优化
查看>>
用C语言操纵Mysql
查看>>
轻松学MVC4.0–6 MVC的执行流程
查看>>
4.9 Parser Generators
查看>>
redis集群如何清理前缀相同的key
查看>>
redis7--hash set的操作
查看>>
20.字典
查看>>
Python 集合(Set)、字典(Dictionary)
查看>>
oracle用户锁定
查看>>
(转)盒子概念和DiV布局
查看>>
Android快速实现二维码扫描--Zxing
查看>>