在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 sys
sys.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

国外参考资料

Python从内存中使用编译后的模块的更多相关文章

  1. Spark(Python) 从内存中建立 RDD 的例子

    Spark(Python) 从内存中建立 RDD 的例子: myData = ["Alice","Carlos","Frank"," ...

  2. 在J2EE的Web应用中,编译后的class文件存放的目录为(选择1项)

    在J2EE的Web应用中,编译后的class文件存放的目录为(选择1项) A. classes目录 B. images目录 C. jar目录 D. 任意位置 解答:A

  3. 查看eclipse web项目中jsp编译后的servlet源文件【转】【JSP】

    eclipse中,jsp编译后 servlet源文件的位置为: F:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wor ...

  4. python 在内存中处理tar.bz2文件

    如果tar.bz2文件是通过网络进行下载,那么可以直接在内存进行解压后读取文件内容,不用将文件缓存到本地然后解压再进行读取,可以节省IO. 处理经过gzip压缩的tar文件的方法见:https://s ...

  5. jenkins自动部署应用到tomcat中,编译后shell脚本的简单示例

    jenkins的安装这里就不做描述了,很简单的  百度搜索一下即可 这里安装的jenkins-2.39-1.1 wget http://pkg.jenkins-ci.org/redhat/jenkin ...

  6. Android SDCard和内部存储中gcc编译后的可执行文件无法运行提示 cannot execute - Permission denied

    原因是mount的方式问题,root后运行 su mount -o rw,remount /mnt/sdcard   //SDCard mount -o rw,remount /mnt/interna ...

  7. vue项目中打包编译后,CSS样式【-webkit-box-orient: vertical】打包后丢失问题

    最近在做vue项目的时候页面处理多行文本样式时用到了-webkit-box-orient: vertical这个属性,本地跑项目没问题,但是打包放到服务器后发现这个属性丢失了.如下图: 后来在网上查了 ...

  8. Python清理内存中的密码

    基本不太好搞.可以参考如下讨论: http://stackoverflow.com/questions/728164/securely-erasing-password-in-memory-pytho ...

  9. IDEA 中,编译后不拷贝 mybatis 配置的 mapper 的 xml 文件

    在maven项目的pom.xml配置文件里添加 <build> <resources> <resource> <directory>src/main/j ...

随机推荐

  1. 开始学CI

    未来一段时间的学习计划 1.codeIgniter 2.angular JS 深入 3.react 4.python 边工作边学习,保持进步

  2. Monte Carlo 数值积分

    var amount = 0.0d; var hitTheTargetCount = 0.0d; var M = 2.0d; var rnd=new Random(); ; i < ; i++) ...

  3. Linux下好玩的命令

    1.yes命令,输出很多个y,可以用来对付选择很多y/n的应用. 2.banner命令,打印字符标题,就是用字符拼出大字来: 3.ddate命令,把日历转换成其他的什么历: 4.fortune命令,随 ...

  4. codeforces 429E

    题意:给定n<=100000线段[l,r],然后给这些线段染色(red or blue),求最后平面上任意一个点被蓝色及红色覆盖次数只差的绝对值不大于1 思路:把每条线段拆成2个点[l<& ...

  5. Sql语句,先查询再插入一条语句完成。

    if ( (select COUNT(*) from Hr where 考勤号码 = '149' and 日期时间 = '2015/7/3 12:00:26') = 0 )INSERT  INTO [ ...

  6. newLISP 10.5.3 发布,类 Lisp 的脚本语言

    newLISP 10.5.3 修复了一些 bug ,为 KMEANS 集群分析器增加了一些函数. newLISP是一个类似Lisp语言的.用于一般用途的脚本语言.它具有 LISP 语言所有的魔力,但更 ...

  7. Android 5.x特性概览三

    上节,对Material Design样式做了介绍,这节我们介绍Palette. 在Android发展的长河中,UI越来越成为Google的发展重心.上文提到Android 5.x 使用palette ...

  8. 统计《ASP.Net特供视频教程》总长度

    忽然想统计一下我录制过的视频一共多长时间,由于视频文件很多,一共72个,挨个打开进行累加不是程序员应该想起的办法.所以就打算写一个程序来完成这件事,最核心的问题就是“获得一个视频文件的时长”. ffm ...

  9. C#学习之Linq to Xml

    前言 我相信很多从事.NET开发的,在.NET 3.5之前操作XML会比较麻烦,但是在此之后出现了Linq to Xml,而今天的主人公就是Linq to Xml,废话不多说,直接进入主题. 题外:最 ...

  10. webpy使用笔记(二) session/sessionid的使用

    webpy使用笔记(二) session的使用 webpy使用系列之session的使用,虽然工作中使用的是django,但是自己并不喜欢那种大而全的东西~什么都给你准备好了,自己好像一个机器人一样赶 ...