As stated by pickle
documentation:
When a pickled class instance is unpickled, its
__init__()
method is normally not invoked.
In your case you do want to invoke __init__
. However since your class is a new-style class you cannot use __getinitargs__
(which isn't supported in python3 anyway). You could try to write your custom __getstate__
and __setstate__
methods:
class Foo(dict):
def __init__(self):
self.counter = 0
def __getstate__(self):
return (self.counter, dict(self))
def __setstate__(self, state):
self.counter, data = state
self.update(data) # will *not* call __setitem__
def __setitem__(self, key, value):
self.counter += 1
super(Foo, self).__setitem__(key, value)
However this still doesn't work, because since you are subclassing dict
and dict
has a special handler for pickling, the __getstate__
method is called, however the __setstate__
method is not.
You can work around this defining the __reduce__
method:
class Foo(dict):
def __init__(self):
self.counter = 0
def __getstate__(self):
return (self.counter, dict(self))
def __setstate__(self, state):
self.counter, data = state
self.update(data)
def __reduce__(self):
return (Foo, (), self.__getstate__())
def __setitem__(self, key, value):
self.counter += 1
super(Foo, self).__setitem__(key, value)