He aquí un sencillo ejemplo de cómo modificar el comportamiento de estibado de una clase. La clase TextReader abre un fichero de texto y devuelve el número de línea y su contenido cada vez que se llama a si método readline(). Si se estiba una instancia de TextReader, se guardan todos los atributos excepto el miembro que guarda el objeto fichero abierto. Al desestibar la instancia, se reabre el fichero y se reanuda la lectura desde la última posición. Se utilizan los métodos __setstate__() y __getstate__() para implementar este comportamiento.
# ilustrata los métodos __setstate__ y __getstate__ # que se utilizan en el estibado. class TextReader: "Presenta y numera líneas de un fichero de texto." 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]) # devuelve la representación de los datos del objeto estibado def __getstate__(self): odict = self.__dict__ # obtiene el diccionario de atributos del odict['fh'] # elimina la entrada del gestor del fichero return odict # restaura el estado del objeto a partir de la representación de datos generada # por __getstate__ def __setstate__(self,dict): fh = open(dict['file']) # reabre el fichero count = dict['lineno'] # lee del fichero... while count: # hasta que se iguala la cuenta de líneas fh.readline() count = count - 1 dict['fh'] = fh # crea la entrada del gestor del fichero self.__dict__ = dict # hace de dict nuestro diccionario de atributos
Un ejemplo de uso:
>>> import TextReader >>> obj = TextReader.TextReader("TextReader.py") >>> obj.readline() '1: #!/usr/local/bin/python' >>> # (más llamadas a obj.readline() aquí) ... obj.readline() '7: class TextReader:' >>> import pickle >>> pickle.dump(obj,open('save.p','w')) (se arranca otra sesión del intérprete de Python) >>> import pickle >>> reader = pickle.load(open('save.p')) >>> reader.readline() '8: "Presenta y numera líneas de un fichero de texto."'