Here's a simple example of how to modify pickling behavior for a class. The TextReader class opens a text file, and returns the line number and line contents each time its readline() method is called. If a TextReader instance is pickled, all attributes except the file object member are saved. When the instance is unpickled, the file is reopened, and reading resumes from the last location. The __setstate__() and __getstate__() methods are used to implement this behavior.
# illustrate __setstate__ and __getstate__ methods # used in pickling. class TextReader: "Print and number lines in a text file." def __init__(self,file): self.file = file self.fh = open(file,'r') self.lineno = 0 def readline(self): self.lineno = self.lineno + 1 line = self.fh.readline() if not line: return None return "%d: %s" % (self.lineno,line[:-1]) # return data representation for pickled object def __getstate__(self): odict = self.__dict__ # get attribute dictionary del odict['fh'] # remove filehandle entry return odict # restore object state from data representation generated # by __getstate__ def __setstate__(self,dict): fh = open(dict['file']) # reopen file count = dict['lineno'] # read from file... while count: # until line count is restored fh.readline() count = count - 1 dict['fh'] = fh # create filehandle entry self.__dict__ = dict # make dict our attribute dictionary
A sample usage might be something like this:
>>> import TextReader >>> obj = TextReader.TextReader("TextReader.py") >>> obj.readline() '1: #!/usr/local/bin/python' >>> # (more invocations of obj.readline() here) ... obj.readline() '7: class TextReader:' >>> import pickle >>> pickle.dump(obj,open('save.p','w')) (start another Python session) >>> import pickle >>> reader = pickle.load(open('save.p')) >>> reader.readline() '8: "Print and number lines in a text file."'