Простой пример использования __setstate__ и __getstate__

Я не знаю, что __setstate__ методы __setstate__ и __getstate__ , поэтому помогите мне с простым примером.

  • Программно определить расположение файлов данных distutils в Python
  • sklearn - Перекрестная проверка с несколькими баллами
  • как сделать мой скрипт python легко переносимым? или как скомпилировать в двоичные файлы со всеми зависимостями модулей?
  • Dataframe в массив numpy со значениями, разделенными запятыми
  • Не удается запустить bjam для компиляции обучающего курса boost python
  • передать сеансовые куки в http-заголовок с python urllib2?
  • MSSQL2008 - Pyodbc - Предыдущий SQL не был запросом
  • SOAP suds и ужасная схема Тип Не найдена ошибка
  • 3 Solutions collect form web for “Простой пример использования __setstate__ и __getstate__”

    Вот очень простой пример для Python 2, который должен дополнять документы 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:", d self.__dict__ = d self.val *= 3 import pickle f = Foo() f_string = pickle.dumps(f) f_new = pickle.loads(f_string) 

    Минимальный пример

    Все, что приходит из getstate , переходит в setstate . Он не должен быть диктором.

    Все, что выходит из getstate должно быть подбираемым, например, состоящим из базовых встроенных элементов, таких как 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 , по умолчанию используется ish:

     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__ default 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 di == 1 assert dj == 2 

    Наследование пользовательское __getstate__

    Без __slots__ это легко, так как __dict__ для D содержит __dict__ для C , поэтому нам вообще не нужно касаться 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 di == 1 assert dj == 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 di == 1 assert dj == 2 

    К сожалению, невозможно повторно использовать значения по умолчанию __getstate__ и __setstate__ базы: https://groups.google.com/forum/#!topic/python-ideas/QkvOwa1-pHQ, которые мы вынуждены определить.

    Протестировано на Python 2.7.12. GitHub вверх по течению: https://github.com/cirosantilli/python-cheat/blob/master/pickle_cheat.py

    Эти методы используются для управления тем, как объекты маринуются и рассыпаются модулем рассола . Обычно это обрабатывается автоматически, поэтому, если вам не нужно переоценивать, как класс маринован или рассыпан, вам не нужно беспокоиться об этом.

    Python - лучший язык программирования в мире.