##
3.14.7 Example

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.

    class TextReader:
        """Print and number lines in a text file."""
        def __init__(self, file):
            self.file = file
            self.fh = open(file)
            self.lineno = 0

        def readline(self):
            self.lineno = self.lineno + 1
            line = self.fh.readline()
            if not line:
                return None
            if line.endswith("\n"):
                line = line[:-1]
            return "%d: %s" % (self.lineno, line)

        def __getstate__(self):
            odict = self.__dict__.copy() # copy the dict since we change it
            del odict['fh']              # remove filehandle entry
            return odict

        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
            self.__dict__.update(dict)   # update attributes
            self.fh = fh                 # save the file object

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'))

If you want to see that `pickle` works across Python processes, start another Python session, before continuing. What follows can happen from either the same process or a new process.

    >>> import pickle
    >>> reader = pickle.load(open('save.p'))
    >>> reader.readline()
    '8:     "Print and number lines in a text file."'

See Also:

Module `copy_reg`:
  Pickle interface constructor registration for extension types.

Module `shelve`:
  Indexed databases of objects; uses `pickle`.

Module `copy`:
  Shallow and deep object copying.

Module `marshal`:
  High-performance serialization of built-in types.