2014-05-14 8 views
5

Ich bin noch ziemlich neu in Python und noch neuer zum Beizen. Ich habe eine Klasse Vertex(ScatterLayout) mit einem __getnewargs__():Beizen Schwachstelle in Python

def __getnewargs__(self): 
    return (self.pos, self.size, self.idea.text) 

Mein Verständnis ist, dass dies die Beize bewirkt das Objekt aus __getnewargs__() anstatt das Objekt Wörterbuch beizen.

Die Gurke wird in dem folgenden Verfahren (in einer anderen Klasse MindMapApp(App)) genannt:

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() 

Als ich die save() Methode, die ich die folgende Fehlermeldung erhalten rufen:

pickle.PicklingError: Can't pickle <type 'weakref'>: it's not found as __builtin__.weakref 

Was bin ich fehlt oder nicht verstehen? Ich habe auch versucht, die __getstate__()/ Kombination mit dem gleichen Ergebnis zu implementieren.

+0

meinst du Klasse __getnewargs__ hat und das wird Fehler verursachen, wenn pickle.dump tun (a), wenn Angenommen, Klasse A und a = A()? Weil ich es versuche und keine Fehlerrückgabe, könnten Sie mehr Details über Problem geben? mag, wie deine Klasse definiert – linpingta

+0

Ich denke, das Problem ist, dass ich zwei Dinge wissen muss: a) Wie man mit Schwächen umgehen, wenn eine Klasse in Essig eingelegt wird; b) Warum wird ein weakref erzeugt, wenn die Items, die gebeizt werden, von '__getnewargs __()' zurückgegeben werden. –

+0

Sie picken nicht die Klasseninstanz (d. H. 'Self'), Sie beizen' Vertices'. Das ist vermutlich ein "weakref". – roippi

Antwort

5

Sie können auf jeden Fall ein weakref beizen, und Sie können ein dict und ein list beizen. Es ist jedoch wichtig, was sie enthalten. Wenn die dict oder list nicht abrufbare Elemente enthält, schlägt das Beizen fehl. Wenn Sie ein weakref picken möchten, müssen Sie dill und nicht pickle verwenden. Die nicht entnommenen weakref deserialisieren jedoch als tote Referenzen.

>>> 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

ich um dieses arbeitete von in __getstate__/__setstate__ zwischen schwach/stark Referenzschalt:

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']) 
Verwandte Themen