簡體   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