2016-07-06 114 views
0

我一直在嘗試使用下面的Python函數加載一個Python泡菜文件:Pickle文件導入錯誤

import os 
import cPickle as pickle 

def load_var(var_name): 
    fid = open(var_name + '.pkl', 'rb') 
    data = pickle.load(fid) 
    fid.close() 
    return data 

,但我一直運行到以下錯誤:

ImportError: No module named sysid_functions 

它抱怨在pickle.py文件中調用一個名爲sysid的模塊。如果我進口的泡菜代替(如cPickle的鹹菜),我得到以下更詳細的錯誤輸出:

File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1378, in load 
    return Unpickler(file).load() 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 858, in load 
    dispatch[key](self) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1090, in load_global 
    klass = self.find_class(module, name) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1124, in find_class 
    __import__(module) 
ImportError: No module named sysid_functions 

沒有任何人有任何想法可能導致錯誤?

+0

你有相應的寫入pickle文件嗎? –

+0

你是什麼意思相應的寫?我得到了一組.pkl文件,並且我正在嘗試使用上述方法讀取這些文件。 – user2480019

+0

你的帖子中不清楚。我想也許你也寫了pkl文件。我想這將是一個很好的第一步,它是否與你創建的一個pickle文件一起工作? –

回答

1

Pickle文件實際上並不存儲類或模塊定義。他們只存儲屬性值。這樣做的好處是可以挑出一個對象,更新源代碼中的類定義,然後讀入pickled數據,它將使用新的類定義,而不是具有相同類的兩個不同版本。

缺點是pickle文件在不同的python環境之間並不能真正傳輸(並且不能可靠地跨越不同的python文件或模塊傳輸)。當涉及到加載一個類或對象時,pickle文件使用與pickle創建時相同的import結構/名稱空間。這意味着從定義一個類的相同模塊創建的pickle文件只能在同一個模塊中重新加載(除非您手動將該類導入到全局名稱空間中)。

對於我們所知的所有sysid_functions是其他一些未安裝的軟件包的子模塊。即使你已經安裝了它,你也可能只能加載pickle文件,如果你管理設置你的模塊globals()就像創建pickle文件的模塊設置一樣。

+0

如果使用'json'或'yaml',這個問題會消失嗎? –

+0

@busfault No.問題不在於序列化格式。問題是試圖序列化一個複雜的數據類型。實際上,json或yaml只支持序列化基本數據類型。除非您提供自定義編碼器/解碼器,否則這些庫甚至不會嘗試序列化自定義類。 –