我有一个pickle转储,它有一个foo.Bar()对象数组。我试图取消它,但Bar()类定义在同一个文件中试图取消,而不是在foo模块中。所以,泡菜抱怨它找不到模块foo。
我试图注入foo模块做类似的事情: import imp,sys
class Bar:
pass
foo_module = imp.new_module('foo')
foo_module.Bar = Bar
sys.modules['foo'] = foo_module
import foo
print foo.Bar()
哪个有效,但在我尝试添加之后:
import pickle
p = pickle.load(open("my-pickle.pkl"))
我收到了友好的错误:
Traceback (most recent call last): File "pyppd.py", line 69, in ppds = loads(ppds_decompressed) File "/usr/lib/python2.6/pickle.py", line 1374, in loads return Unpickler(file).load() File "/usr/lib/python2.6/pickle.py", line 858, in load dispatch[key](self) File "/usr/lib/python2.6/pickle.py", line 1069, in load_inst klass = self.find_class(module, name) File "/usr/lib/python2.6/pickle.py", line 1124, in find_class __import__(module) File "/tmp/test.py", line 69, in p = pickle.load(open("my-pickle.pkl")) File "/usr/lib/python2.6/pickle.py", line 1374, in loads return Unpickler(file).load() File "/usr/lib/python2.6/pickle.py", line 858, in load dispatch[key](self) File "/usr/lib/python2.6/pickle.py", line 1069, in load_inst klass = self.find_class(module, name) File "/usr/lib/python2.6/pickle.py", line 1124, in find_class __import__(module) ImportError: No module named foo
有什么想法吗?
答案 0 :(得分:3)
class Bar:
pass
class MyUnpickler(pickle.Unpickler):
def find_class(self, module, name):
if module == "foo" and name == "Bar":
return Bar
else:
return pickle.Unpickler.find_class(self, module, name)
bars = MyUnpickler(open("objects.pkl")).load()
CAVEAT CAVEAT CAVEAT:
如果您从另一个模块调用此代码段,请说baz
,那么未打开的对象将是baz.Bar
类型,而不是foo.Bar
。假设foo.Bar
和baz.Bar
的类定义相同,那么您将毫无困难地进行解开。但要注意下游使用isinstance
,type
等。一般来说,尝试为一次性而做任何事情都可能不聪明,因为你的代码库现在包含两个实例Bar
。如果可能的话,你应该把foo
放在你的路径中。