Ich weiß nicht, was die __setstate__
und __getstate__
Methoden tun, also helfen Sie mir mit einem einfachen Beispiel.
python
serialization
zjm1126
quelle
quelle
Antworten:
Hier ist ein sehr einfaches Beispiel für Python, das die Pickle-Dokumente ergänzen sollte .
class Foo(object): def __init__(self, val=2): self.val = val def __getstate__(self): print("I'm being pickled") self.val *= 2 return self.__dict__ def __setstate__(self, d): print("I'm being unpickled with these values: " + repr(d)) self.__dict__ = d self.val *= 3 import pickle f = Foo() f_data = pickle.dumps(f) f_new = pickle.loads(f_data)
quelle
Minimales Beispiel
Was auch immer herauskommt
getstate
, geht hineinsetstate
. Es muss kein Diktat sein.Was auch immer kommt aus
getstate
muss pickeable, zum Beispiel aus dem Grunde Einbauten wieint
,str
,list
.class C(object): def __init__(self, i): self.i = i def __getstate__(self): return self.i def __setstate__(self, i): self.i = i assert pickle.loads(pickle.dumps(C(1), -1)).i == 1
Standard
__setstate__
Der Standardwert ist
__setstate__
adict
.self.__dict__
ist eine gute Wahl wie unter https://stackoverflow.com/a/1939384/895245 , aber wir können selbst eine erstellen, um besser zu sehen, was los ist:class C(object): def __init__(self, i): self.i = i def __getstate__(self): return {'i': self.i} assert pickle.loads(pickle.dumps(C(1), -1)).i == 1
Standard
__getstate__
Analog zu
__setstate__
.class C(object): def __init__(self, i): self.i = i def __setstate__(self, d): self.i = d['i'] assert pickle.loads(pickle.dumps(C(1), -1)).i == 1
__slots__
Objekte haben nicht__dict__
Wenn das Objekt hat
__slots__
, dann hat es nicht__dict__
Wenn Sie beide
get
und implementierensetstate
möchten, lautet die Standardeinstellung:class C(object): __slots__ = 'i' def __init__(self, i): self.i = i def __getsate__(self): return { slot: getattr(self, slot) for slot in self.__slots__ } def __setsate__(self, d): for slot in d: setattr(self, slot, d[slot]) assert pickle.loads(pickle.dumps(C(1), -1)).i == 1
__slots__
Standardmäßig erwartet get and set ein TupelWenn Sie die Standardeinstellung
__getstate__
oder wiederverwenden möchten__setstate__
, müssen Sie Tupel wie folgt weitergeben:class C(object): __slots__ = 'i' def __init__(self, i): self.i = i def __getsate__(self): return (None, { slot: getattr(self, slot) for slot in self.__slots__ }) assert pickle.loads(pickle.dumps(C(1), -1)).i == 1
Ich bin mir nicht sicher, wofür das ist.
Erbe
Stellen Sie zunächst sicher, dass das Beizen standardmäßig funktioniert:
class C(object): def __init__(self, i): self.i = i class D(C): def __init__(self, i, j): super(D, self).__init__(i) self.j = j d = pickle.loads(pickle.dumps(D(1, 2), -1)) assert d.i == 1 assert d.j == 2
Vererbungsgewohnheit
__getstate__
Ohne
__slots__
es ist einfach, da die__dict__
fürD
enthält die__dict__
fürC
, so dass wir berühren nicht brauchenC
überhaupt:class C(object): def __init__(self, i): self.i = i class D(C): def __init__(self, i, j): super(D, self).__init__(i) self.j = j def __getstate__(self): return self.__dict__ def __setstate__(self, d): self.__dict__ = d d = pickle.loads(pickle.dumps(D(1, 2), -1)) assert d.i == 1 assert d.j == 2
Vererbung und
__slots__
Mit
__slots__
müssen wir an die Basisklasse weiterleiten und können Tupel weitergeben:class C(object): __slots__ = 'i' def __init__(self, i): self.i = i def __getstate__(self): return { slot: getattr(self, slot) for slot in C.__slots__ } def __setstate__(self, d): for slot in d: setattr(self, slot, d[slot]) class D(C): __slots__ = 'j' def __init__(self, i, j): super(D, self).__init__(i) self.j = j def __getstate__(self): return ( C.__getstate__(self), { slot: getattr(self, slot) for slot in self.__slots__ } ) def __setstate__(self, ds): C.__setstate__(self, ds[0]) d = ds[1] for slot in d: setattr(self, slot, d[slot]) d = pickle.loads(pickle.dumps(D(1, 2), -1)) assert d.i == 1 assert d.j == 2
Leider ist es nicht möglich, die Standardeinstellung
__getstate__
und__setstate__
die Basis wiederzuverwenden : https://groups.google.com/forum/#!topic/python-ideas/QkvOwa1-pHQ Wir sind gezwungen, sie zu definieren.Getestet auf Python 2.7.12. GitHub stromaufwärts .
quelle
Diese Methoden werden verwendet zur Steuerung , wie Objekte gebeizt und ungebeizt durch die Beize - Modul. Dies wird normalerweise automatisch erledigt. Wenn Sie also nicht überschreiben müssen, wie eine Klasse ausgewählt oder nicht ausgewählt wird, sollten Sie sich darüber keine Gedanken machen müssen.
quelle