Saya tidak tahu apa yang dilakukan __setstate__
dan __getstate__
metode, jadi bantu saya dengan contoh sederhana.
python
serialization
zjm1126
sumber
sumber
Jawaban:
Berikut adalah contoh yang sangat sederhana untuk Python yang harus melengkapi dokumen acar .
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)
sumber
Contoh minimal
Apapun yang keluar
getstate
, masuk ke dalamsetstate
. Ini tidak perlu menjadi dikt.Apa pun yang datang dari
getstate
harus pickeable, misalnya terdiri dari dasar built-in sepertiint
,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
Default
__setstate__
Defaultnya
__setstate__
adalahdict
.self.__dict__
adalah pilihan yang baik seperti di https://stackoverflow.com/a/1939384/895245 , tetapi kita dapat membuatnya sendiri untuk melihat dengan lebih baik apa yang sedang terjadi: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
Default
__getstate__
Analog dengan
__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__
benda tidak punya__dict__
Jika benda tersebut memiliki
__slots__
, maka ia tidak memiliki__dict__
Jika Anda akan menerapkan keduanya
get
dansetstate
, cara default-ishnya adalah: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__
get dan set default mengharapkan tupelJika Anda ingin menggunakan kembali default
__getstate__
atau__setstate__
, Anda harus melewatkan tupel sebagai: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
Saya tidak yakin untuk apa ini.
Warisan
Pertama, lihat bahwa pengawetan berfungsi secara default:
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
Kebiasaan warisan
__getstate__
Tanpanya
__slots__
mudah, karena__dict__
forD
berisi__dict__
forC
, jadi kita tidak perlu menyentuhC
sama sekali: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
Warisan dan
__slots__
Dengan
__slots__
, kita perlu meneruskan ke kelas dasar, dan dapat mengirimkan tupel di sekitar: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
Sayangnya, tidak mungkin menggunakan kembali default
__getstate__
dan__setstate__
basis: https://groups.google.com/forum/#!topic/python-ideas/QkvOwa1-pHQ kami terpaksa mendefinisikannya.Diuji pada Python 2.7.12. GitHub upstream .
sumber
Metode ini digunakan untuk mengontrol bagaimana objek diawetkan dan dilepas oleh modul acar . Ini biasanya ditangani secara otomatis, jadi kecuali Anda perlu menimpa bagaimana kelas diawetkan atau diurai, Anda tidak perlu khawatir tentang itu.
sumber