Pickle all attributes except one

Viewed 7088

What is the best way to write a __getstate__ method that pickles almost all of an object's attributes, but excludes a few?

I have an object with many properties, including one that references an instancemethod. instancemethod's are not pickleable, so I'm getting an error when I try to pickle this object:

class Foo(object):
    def __init__(self):
        self.a = 'spam'
        self.b = 'eggs'
        self.c = 42
        self.fn = self.my_func
    def my_func(self):
        print 'My hovercraft is full of eels'

import pickle
pickle.dumps(Foo())              # throws a "can't pickle instancemethod objects" TypeError

This __getstate__ method fixes this, but then I have to manually include all the properties I want to serialize:

def __getstate__(self):
    return { 'a': self.a, 'b': self.b, 'c': self.c }

That's not very scalable or maintainable if I have an object with many attributes or that changes frequently.

The only alternative I can think of is some kind of helper function that iterates through an object's properties and adds them (or not) to the dictionary, based on the type.

6 Answers

For the your specific case (preventing a function from getting pickled), use this:

self.__class__.fn = self.__class__.my_func

Now, instead of adding a function to an instance of a class, you've added it to the class itself, thus the function won't get pickled. This won't work if you want each instance to have its own version of fn.

My scenario was that I wanted to selectively add get_absolute_url to some Django models, and I wanted to define this in an abstract BaseModel class. I had self.get_absolute_url = … and ran into the pickle issue. Just added __class__ to the assignment solved the issue in my case.

Related