我一直在尝试使用以下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的模块。如果我导入pickle而不是(cPickle as pickle),我会得到以下更详细的错误输出:
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 :(得分:1)
Pickle文件实际上并不存储类或模块定义。它们只存储属性值。这样做的好处是你可以挑出一个对象,更新源代码中的类定义,然后读入pickle数据,它将使用新的类定义,而不是同一个类的两个不同版本。
缺点是pickle文件在不同的python环境之间不能真正转移(并且甚至不能在不同的python文件或模块之间可靠地传输)。在加载类或对象时,pickle文件使用创建pickle时存在的相同导入结构/命名空间。这意味着从定义类的同一模块创建的pickle文件只能在同一模块中重新加载(除非您手动将该类导入到全局名称空间中)。
据我们所知,sysid_functions
是您尚未安装的其他软件包的子模块。即使您确实安装了它,如果您管理设置模块globals()
,您可能只能加载pickle文件,就像设置创建pickle文件的模块一样。