2016-07-06 146 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只支持序列化基本数据类型。除非您提供自定义编码器/解码器,否则这些库甚至不会尝试序列化自定义类。 –