Does inheriting from "objects" break __getstate__ & __setstate__?

Configuring the base class to handle tracking of class instances while retaining garbage collection. The second answer from this post is close, but I also need to add to the list instances

when unpickling from stored instances.

Here is my code:

import weakref
import pickle
from pprint import pprint
import copy

class BaseClass(object):

    def __new__(cls, *args, **kwargs):
        instance = object.__new__(cls, *args, **kwargs)
        if 'instances' not in cls.__dict__:
            cls.instances = []
        cls.instances.append(weakref.ref(instance))
        return instance

    def __getstate__(self):
        print "pickling"
        d = self.__dict__
        return d

    def __setstate__(self, state):
        print "unpickling"
        self.__dict__ = state
        if 'instances' not in self.__dict__:
            self.instances = []
        self.__class__.instances.append(weakref.ref(self))
        return self

BaseClass.instances = []

if __name__ == '__main__':
    a = BaseClass()
    b = BaseClass()
    c = BaseClass()

    pprint(BaseClass.instances)

    f = file("test.pkl","wb")
    pickle.dump(c,f)
    f.close()

    f = file("test.pkl","rb")
    d = pickle.load(f)
    f.close()

    pprint(BaseClass.instances)

      

So the odd thing is that "unpickling" is never printed, and the instance is d

not listed instances

, indicating that it is __setstate__

never called.

If I replace d = pickle.load(f)

with d = copy.copy(pickle.load(f))

, then d

translates it to the list instances

and "etching" twice, not once.

If I changed class BaseClass(object):

to class BaseClass:

, then "etching" and "spilling" of each print once, as expected, and d

will list, but a

, b

and c

do not do.

Does anyone know what's going on? It looks like explicit inheritance from object

breaks the default behavior of __getstate__

and __setstate__

.

+3


source to share





All Articles