python如何导入模块 zip_python从内存加载zip模块

编辑:修正ZipImporter适用于所有事情(我认为)

测试数据:

mkdir mypkg

vim mypkg/__init__.py

vim mypkg/test_submodule.py

__init__.py内容:

def test():

print("Test")

test_submodule.py内容:

def test_submodule_func():

print("This is a function")

创建测试Zip(在mac上):

zip -r mypkg.zip mypkg

rm -r mypkg # don't want to accidentally load the directory

inmem_zip_importer.py中的特殊zip导入:

import os

import imp

import zipfile

class ZipImporter(object):

def __init__(self,zip_file):

self.z = zip_file

self.zfile = zipfile.ZipFile(self.z)

self._paths = [x.filename for x in self.zfile.filelist]

def _mod_to_paths(self,fullname):

# get the python module name

py_filename = fullname.replace(".",os.sep) + ".py"

# get the filename if it is a package/subpackage

py_package = fullname.replace(".",os.sep,fullname.count(".") - 1) + "/__init__.py"

if py_filename in self._paths:

return py_filename

elif py_package in self._paths:

return py_package

else:

return None

def find_module(self,fullname,path):

if self._mod_to_paths(fullname) is not None:

return self

return None

def load_module(self,fullname):

filename = self._mod_to_paths(fullname)

if not filename in self._paths:

raise ImportError(fullname)

new_module = imp.new_module(fullname)

exec self.zfile.open(filename,'r').read() in new_module.__dict__

new_module.__file__ = filename

new_module.__loader__ = self

if filename.endswith("__init__.py"):

new_module.__path__ = []

new_module.__package__ = fullname

else:

new_module.__package__ = fullname.rpartition('.')[0]

return new_module

使用:

In [1]: from inmem_zip_importer import ZipImporter

In [2]: sys.meta_path.append(ZipImporter(open("mypkg.zip","rb")))

In [3]: from mypkg import test

In [4]: test()

Test function

In [5]: from mypkg.test_submodule import test_submodule_func

In [6]: test_submodule_func()

This is a function

(来自efel)还有一件事……:

要直接从内存中读取,需要执行以下操作:

f = open("mypkg.zip","rb")

# read binary data we are now in memory

data = f.read()

f.close() #important! close the file! we are now in memory

# at this point we can essentially delete the actual on disk zip file

# convert in memory bytes to file like object

zipbytes = io.BytesIO(data)

zipfile.ZipFile(zipbytes)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值