Я собирался спросить «Как выделить класс, унаследованный от 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
как часть состояния.
Что ж, это работает ... но может кто-нибудь объяснить почему? Это функция или ошибка?