Я не знаю , что __setstate__
и __getstate__
методы делают, так что помочь мне с простым примером.
python
serialization
zjm1126
источник
источник
Ответы:
Вот очень простой пример для Python, который должен дополнять документацию по pickle .
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)
источник
Минимальный пример
Все, что выходит
getstate
, входит вsetstate
. Это не обязательно должен быть диктат.Все , что выходит из
getstate
должны быть pickeable, например , из основных встроенных функций , таких какint
,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
По умолчанию
__setstate__
По умолчанию используется
__setstate__
расширениеdict
.self.__dict__
- хороший выбор, как в https://stackoverflow.com/a/1939384/895245 , но мы можем создать его сами, чтобы лучше видеть, что происходит: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
По умолчанию
__getstate__
Аналогично
__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__
у объектов нет__dict__
Если у объекта есть
__slots__
, значит, у него нет__dict__
Если вы собираетесь реализовать оба
get
иsetstate
, по умолчанию используется следующий способ: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 и set ожидают кортежЕсли вы хотите повторно использовать значение по умолчанию
__getstate__
или__setstate__
, вам придется передавать кортежи как: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
Я не уверен, для чего это нужно.
Наследование
Сначала убедитесь, что травление работает по умолчанию:
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
Наследование обычай
__getstate__
Без
__slots__
этого легко, поскольку__dict__
forD
содержит__dict__
forC
, поэтому нам вообще не нужно трогатьC
: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
Наследование и
__slots__
С
__slots__
, нам нужно перейти к базовому классу и передать кортежи: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
К сожалению, невозможно повторно использовать значение по умолчанию
__getstate__
и__setstate__
базу: https://groups.google.com/forum/#!topic/python-ideas/QkvOwa1-pHQ, мы вынуждены их определить.Протестировано на Python 2.7.12. GitHub вверх по течению .
источник
Эти методы используются для управления процессом маринования и освобождения объектов модулем pickle . Обычно это обрабатывается автоматически, поэтому, если вам не нужно переопределять способ маринования или выделения класса, вам не нужно об этом беспокоиться.
источник