Мариновать слабонервных в 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'])
Другие вопросы по тегам