繁体   English   中英

从zipfile加载pickle文件

[英]load a pickle file from a zipfile

由于某种原因,我无法让cPickle.load处理ZipFile.open()返回的文件类型对象。 如果我在ZipFile.open()返回的文件类型对象上调用read(),我可以使用cPickle.loads。

示例....

import zipfile
import cPickle

# the data we want to store
some_data = {1: 'one', 2: 'two', 3: 'three'}

#
# create a zipped pickle file
#
zf = zipfile.ZipFile('zipped_pickle.zip', 'w', zipfile.ZIP_DEFLATED)
zf.writestr('data.pkl', cPickle.dumps(some_data))
zf.close()

#
# cPickle.loads works
#
zf = zipfile.ZipFile('zipped_pickle.zip', 'r')
sd1 = cPickle.loads(zf.open('data.pkl').read())
zf.close()

#
# cPickle.load doesn't work
#
zf = zipfile.ZipFile('zipped_pickle.zip', 'r')
sd2 = cPickle.load(zf.open('data.pkl'))
zf.close()

注意:我不想仅仅压缩pickle文件,而是压缩其他类型的许多文件。 这只是一个例子。

这是由于zipfile模块实现的伪文件对象的不完美(对于Python 2.6中引入的ZipFile类的.open方法)。 考虑:

>>> f = zf.open('data.pkl')
>>> f.read(1)
'('
>>> f.readline()
'dp1\n'
>>> f.read(1)
''
>>> 

.read(1) - .readline()的序列是.loads内部做的(在protocol-0 pickle上,Python 2中的默认值,这是你在这里使用的)。 不幸的是, zipfile的不完美意味着这个特定的序列不起作用,在第一个读/读线对之后立即产生虚假的“文件结束”(.read返回一个空字符串)。

如果在Python 2.7中修复了Python标准库中的这个错误,我不确定 - 我要检查一下。

编辑 :刚检查 - 该错误在Python 2.7 rc1(当前最新的2.7版本的候选版本)中得到修复。 我还不知道它是否已修复2.6的最新错误修复版本。

再次编辑 :Python 2.6.5中的错误仍然存​​在,Python 2.6的最新错误修复版本 - 所以如果你不能升级到2.7并且需要ZipFile.open更好的伪文件对象,那么2.7修复似乎是唯一可行的解​​决方案。

请注意,这不是一定的,你需要做的更好,运行得伪文件对象; 如果您控制转储调用并且可以使用最新和最好的协议,一切都会好的:

>>> zf = zipfile.ZipFile('zipped_pickle.zip', 'w', zipfile.ZIP_DEFLATED)
>>> zf.writestr('data.pkl', cPickle.dumps(some_data, -1))
>>> sd2 = cPickle.load(zf.open('data.pkl'))
>>> 

它只是老式的向后兼容“协议0”(默认),在load读取和读取线调用时需要适当的伪文件对象行为(协议0也较慢,导致较大的泡菜,所以除非向后,否则绝对不推荐使用与旧Python版本的兼容性,或者0生成的pickle的ascii-only性质,是应用程序中的强制约束)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM