3.14.7 Esempio

Ecco un semplice esempio di come modificare il comportamento di serializzazione (pickling) per una classe. La classe TextReader apre un file di testo e restituisce il numero di riga ed il suo contenuto, ogni volta che viene invocato il suo metodo readline(). Se viene serializzata un'istanza di TextReader, tutti gli attributi eccetto l'oggetto membro di tipo file vengono salvati. Quando l'istanza viene deserializzata, il file viene riaperto e l'operazione di lettura riprende dall'ultima posizione. I metodi __setstate__() e __getstate__() vengono utilizzati per implementare questo comportamento.

class TextReader:
    """Stampa numero e contenuto di ogni riga in un 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() # copia il dizionario perchè stiamo per modificarlo
        del odict['fh']              # rimuove la voce del filehandle
        return odict

    def __setstate__(self,dict):
        fh = open(dict['file'])      # apre nuovamente il file
        count = dict['lineno']       # legge dal file...
        while count:                 # finché il contatore viene ripristinato
            fh.readline()
            count = count - 1
        self.__dict__.update(dict)   # aggiorna gli attributi
        self.fh = fh                 # salva il file oggetto

Un semplice uso potrebbe essere il seguente:

>>> import TextReader
>>> obj = TextReader.TextReader("TextReader.py")
>>> obj.readline()
'1: #!/usr/local/bin/python'
>>> # (qui altre invocazioni di obj.readline())
... obj.readline()
'7: class TextReader:'
>>> import pickle
>>> pickle.dump(obj,open('save.p','w'))

Se desiderate vedere come pickle lavora tramite i processi Python, avviate un'altra sessione di Python, prima di continuare. Quello che segue può avvenire sia nello stesso processo che in uno nuovo.

>>> import pickle
>>> reader = pickle.load(open('save.p'))
>>> reader.readline()
'8:     "Stampa e numera righe in un file di testo."'

Vedete anche:

Modulo copy_reg:
Interfaccia Pickle per la registrazione dei costruttori per i tipi di estensione.

Modulo shelve:
Database indicizzato di oggetti; usa pickle.

Modulo copy:
Copia di oggetti superficiale e profonda.

Modulo marshal:
Serializzazione ad alte prestazione dei tipi built-in.

Vedete Circa questo documento... per informazioni su modifiche e suggerimenti.