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:
Vedete Circa questo documento... per informazioni su modifiche e suggerimenti.