Почему pickle __getstate__ принимает в качестве возвращаемого значения именно тот экземпляр, который ему нужен __getstate__ в первую очередь для маринования?

Я собирался спросить «Как выделить класс, унаследованный от dict и определяет __ slots __ ". Затем я понял, что чрезвычайно сложное решение в классе B ниже действительно работает ...

import pickle

class A(dict):
    __slots__ = ["porridge"]
    def __init__(self, porridge): self.porridge = porridge

class B(A):
    __slots__ = ["porridge"]
    def __getstate__(self):
        # Returning the very item being pickled in 'self'??
        return self, self.porridge 
    def __setstate__(self, state):
        print "__setstate__(%s) type(%s, %s)" % (state, type(state[0]), 
                                                type(state[1]))
        self.update(state[0])
        self.porridge = state[1]

Вот некоторые результаты:

>>> saved = pickle.dumps(A(10))
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled
>>> b = B('delicious')
>>> b['butter'] = 'yes please'
>>> loaded = pickle.loads(pickle.dumps(b))
__setstate__(({'butter': 'yes please'}, 'delicious')) type(<class '__main__.B'>, <type 'str'>)
>>> b
{'butter': 'yes please'}
>>> b.porridge
'delicious'

Итак, в основном, pickle не может обработать класс, который определяет __ slots __ , не определяя также __ getstate __ . Это проблема, если класс наследуется от dict - потому что как вы вернуть содержимое экземпляра, не возвращая self , который является тем самым экземпляром pickle, который уже пытается обработать, и не может сделать это без вызова __ getstate __ . Обратите внимание, как __ setstate __ на самом деле получает экземпляр B как часть состояния.

Что ж, это работает ... но может кто-нибудь объяснить почему? Это функция или ошибка?

11
задан Eric O Lebigot 1 March 2013 в 03:21
поделиться