Pickle文件导入错误
我一直在尝试使用下面的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
没有任何人有任何想法可能导致错误?
Pickle文件实际上并不存储类或模块定义。他们只存储属性值。这样做的好处是可以挑出一个对象,更新源代码中的类定义,然后读入pickled数据,它将使用新的类定义,而不是具有相同类的两个不同版本。
缺点是pickle文件在不同的python环境之间并不能真正传输(并且不能可靠地跨越不同的python文件或模块传输)。当涉及到加载一个类或对象时,pickle文件使用与pickle创建时相同的import结构/名称空间。这意味着从定义一个类的相同模块创建的pickle文件只能在同一个模块中重新加载(除非您手动将该类导入到全局名称空间中)。
对于我们所知的所有sysid_functions
是其他一些未安装的软件包的子模块。即使你已经安装了它,你也可能只能加载pickle文件,如果你管理设置你的模块globals()
就像创建pickle文件的模块设置一样。
如果使用'json'或'yaml',这个问题会消失吗? –
@busfault No.问题不在于序列化格式。问题是试图序列化一个复杂的数据类型。实际上,json或yaml只支持序列化基本数据类型。除非您提供自定义编码器/解码器,否则这些库甚至不会尝试序列化自定义类。 –
你有相应的写入pickle文件吗? –
你是什么意思相应的写?我得到了一组.pkl文件,并且我正在尝试使用上述方法读取这些文件。 – user2480019
你的帖子中不清楚。我想也许你也写了pkl文件。我想这将是一个很好的第一步,它是否与你创建的一个pickle文件一起工作? –