tags:

views:

180

answers:

4

I want my class to implement Save and Load functions which simply do a pickle of the class. But apparently you cannot use 'self' in the fashion below. How can you do this?

    self = cPickle.load(f)

    cPickle.dump(self,f,2)
+1  A: 

There is an example of how to pickle an instance here, in the docs. (Search down for the "TextReader" example). The idea is to define __getstate__ and __setstate__ methods, which allow you to define what data needs to be pickled, and how to use that data to re-instantiate the object.

unutbu
This doesn't solve the problem because you still cannot inside the class's Load function call self = cPickle.load(f) in order to fill the class with the loaded data.Or course I can pickle the class data itself, but I'm trying to avoid writing all that code and being forced to update it when the class member variables change.
Mark
+2  A: 

The dump part should work as you suggested. for the loading part, you can define a @classmethod that loads an instance from a given file and returns it.

@classmethod
def loader(cls,f):
    return cPickle.load(f)

then the caller would do something like:

class_instance = ClassName.loader(f)
Ofri Raviv
So what you are saying is with class Foo, instance foo I can do foo.Save() but I cannot do foo.Load() I would have to do foo = foo.Load() -- (class methods can be called with an instance or class name)
Mark
It makes perfect sense that you should use foo=Foo.load(), and not foo=Foo();foo.load(). for example, if Foo has some variables that MUST be passed in to the init, you would need to make them up for foo=Foo(); or if the init does some heavy calculations of variables stored in the instance, it would be for nothing.
Ofri Raviv
This works, originally I hadfoo = Foo('somefilename')And Foo was doing its own loading of its data. Now I do a:foo = Foo.Load('somefilename')If I modify the definition of Foo, I can still use the new functions/members in the pickle loaded foo instance.
Mark
A: 

How about writing a class called Serializable that would implement dump and load and make your class inherit from it?

Alex K
+1  A: 

This is what I ended up doing. Updating the __dict__ means we keep any new member variables I add to the class and just update the ones that were there when the object was last pickle'd. It seems the simplest while maintaining the saving and loading code inside the class itself so calling code just does an object.Save().

def Load(self):
    f = open(self.filename,'rb')
    tmp_dict = cPickle.load(f)
    f.close()          

    self.__dict__.update(tmp_dict) 


def Save(self):
    f = open(self.filename,'wb')
    cPickle.dump(self.__dict__,f,2)
    f.close()
Mark