我仍然是Python的新手,甚至更新的酸洗。我的课程Vertex(ScatterLayout)
有__getnewargs__()
:
def __getnewargs__(self):
return (self.pos, self.size, self.idea.text)
我的理解是,这将导致pickle从__getnewargs__()
而不是对象的字典中腌制对象。
使用以下方法(在不同的类MindMapApp(App)
中)调用pickle:
def save(self):
vertices = self.mindmap.get_vertices()
edges = self.mindmap.get_edges()
output = open('mindmap.pkl', 'wb')
#pickle.dump(edges, output, pickle.HIGHEST_PROTOCOL)
pickle.dump(vertices, output, pickle.HIGHEST_PROTOCOL)
output.close()
当我调用save()
方法时,我收到以下错误:
pickle.PicklingError: Can't pickle <type 'weakref'>: it's not found as __builtin__.weakref
我缺少什么或不理解?我也尝试过实施__getstate__()
/ __setstate__(state)
组合,结果相同。
答案 0 :(得分:7)
你绝对可以挑选weakref
,你可以挑选dict
和list
。
然而,实际上它们包含的内容很重要。如果dict
或list
包含不可推断的intems,则酸洗将失败。如果您要挑选weakref
,则必须使用dill
而不是pickle
。然而,未被删除的weakref
反序列化为死引用。
>>> import dill
>>> import weakref
>>> dill.loads(dill.dumps(weakref.WeakKeyDictionary()))
<WeakKeyDictionary at 4528979192>
>>> dill.loads(dill.dumps(weakref.WeakValueDictionary()))
<WeakValueDictionary at 4528976888>
>>> class _class:
... def _method(self):
... pass
...
>>> _instance = _class()
>>> dill.loads(dill.dumps(weakref.ref(_instance)))
<weakref at 0x10d748940; dead>
>>> dill.loads(dill.dumps(weakref.ref(_class())))
<weakref at 0x10e246a48; dead>
>>> dill.loads(dill.dumps(weakref.proxy(_instance)))
<weakproxy at 0x10e246b50 to NoneType at 0x10d481598>
>>> dill.loads(dill.dumps(weakref.proxy(_class())))
<weakproxy at 0x10e246ba8 to NoneType at 0x10d481598>
答案 1 :(得分:3)
我通过在__getstate__
/ __setstate__
中切换弱/强引用来解决这个问题:
class DBObject(object):
def __getstate__(self):
s = self.__dict__.copy()
s['_db'] = s['_db']()
return s
def __setstate__(self, state):
self.__dict__ = state.copy()
self.__dict__['_db'] = weakref.ref(self.__dict__['_db'])