在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

国外参考资料

最新文章

  1. python Queue模块
  2. liMarquee演示12种不同的无缝滚动效果
  3. git 教程(11)--从远程库克隆
  4. Xamarin.Forms——WebView技术研究
  5. Windows python3.3下安装BeautifulSoup
  6. ubuntu14.10建立热点wifi分享给手机
  7. sizeof()和strlen()的区别与联系
  8. Fury观后感
  9. java SWT/Rap 计算器版本2(键盘鼠标兼容)
  10. C#位移运算符
  11. Php5.3的lambda函数以及closure(闭包)
  12. iOS图片拉伸技巧-李明杰分享
  13. “psql: could not connect to server: Connection refused” Error when connecting to remote database
  14. .Net cache与cache更新
  15. Java核心技术梳理-基础类库
  16. java 深度复制与浅复制 copyOf、arraycopy、copyOfRange
  17. JS的防抖与节流
  18. 08 LaTeX学习系列之---Latex 的中文操作
  19. [CNBETA]动图告诉你 光速到底有多慢?
  20. ABP之展现层(导航菜单)

热门文章

  1. matlab微分方程dsolve使用
  2. JavaScript-join连接符
  3. java线程详解(二)
  4. opengles2.0 学习笔记
  5. 解决Win7下打不开chm文件的方法
  6. day5----模块
  7. 最常用的PHP正则表达式收集整理
  8. C#结合LumiSoft.Net.dll读取Outlook邮件(.eml格式邮件)
  9. PDB调试Python程序
  10. Openstack Murano(kilo)二次开发之添加Volume