Мариновать слабонервных в Python
Я все еще довольно новичок в Python и еще новее в мариновании. У меня есть класс Vertex(ScatterLayout)
с __getnewargs__()
:
def __getnewargs__(self):
return (self.pos, self.size, self.idea.text)
Насколько я понимаю, это приведет к засолке объекта из __getnewargs__()
а не словарь объекта.
Рассол вызывается в следующем методе (в другом классе MindMapApp(App)
):
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)
комбинация, с тем же результатом.
2 ответа
Вы определенно можете мариновать weakref
и вы можете мариновать dict
и list
, Тем не менее, это действительно имеет значение, что они содержат. Если dict
или же list
содержит необратимые целые, тогда травление не удастся. Если вы хотите мариновать 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>
Я работал над этим, переключаясь между слабой / сильной ссылкой в __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'])