3.11.1 Exemple

Voici un exemple simple de la façon de modifier le comportement de picklage pour une classe. La classe TextReader ouvre un fichier texte, et retourne le numéro et le contenu de la ligne à chaque fois que sa méthode readline() est appelée. Si une instance de TextReader est picklée, tous les attributs sauf l'objet fichier sont sauvegardés. Quand l'instance est dépicklée, le fichier est réouvert, et la lecture se poursuit à partir de la dernière position. Les méthodes __setstate__() et __getstate__() servent à implémenter ce comportement.

# illustre les méthodes __setstate__ et __getstate__ 
# utilisées dans le picklage.


class TextReader:
    "Affiche et numérote les lignes dans un fichier texte."
    def __init__(self,fichier):
        self.fichier = fichier
        self.fh = open(fichier,'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])

    # retourne la représentation des données pour l'objet picklé
    def __getstate__(self):
        odict = self.__dict__    # get attribute dictionary
        del odict['fh']          # remove filehandle entry
        return odict

    # restaure l'état de l'objet à partir de la représentation des données générée
    # avec __getstate__
    def __setstate__(self,dict):
        fh = open(dict['file'])  # rouvre le fichier
        count = dict['lineno']   # lit depuis le fichier...
        while count:             # jusqu'à ce que le compteur de lignes soit restauré
            fh.readline()
            count = count - 1
        dict['fh'] = fh          # crée une entrée avec le handle du fichier
        self.__dict__ = dict     # fait de dict notre dictionnaire d'attributs

Un exemple d'utilisation pourrait être du genre suivant:

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

  (commence une autre session Python)

>>> import pickle
>>> reader = pickle.load(open('save.p'))
>>> reader.readline()
'8:	"Affiche et numérote les lignes dans un fichier texte."'