2010-06-08 9 views
16

Estoy usando gnosis.xml.pickle para convertir un objeto de mi propia clase en xml. El objeto se inicializa de forma que:Cómo detener la exclusión de atributos en Python

self.logger = MyLogger() 

Pero cuando lo haga volcar el objeto a una cadena consigo una excepción que indica que el pickler encontró un tipo unpickleable (thread.lock).

¿Hay alguna manera de "etiquetar" el atributo del registrador para que el recolector sepa que no debe intentar y conservar ese atributo?

Respuesta

29

Puede definir dos métodos, __getstate__ y __setstate__, a su clase para anular el comportamiento de decapado predeterminado.

http://docs.python.org/library/pickle.html#object.__getstate__

__getstate__ debe devolver un diccionario de atributos que desea conservar en vinagre.

def __getstate__(self): 
    d = dict(self.__dict__) 
    del d['logger'] 
    return d 

__setstate__ debe configurar el objeto con el dict proporcionado.

def __setstate__(self, d): 
    self.__dict__.update(d) # I *think* this is a safe way to do it 

Tenga en cuenta que __init__ no se llamará cuando deserialiación por lo que usted tiene que crear su registrador en __setstate__

+0

gracias. tenga en cuenta que estoy usando la gnosis pickle lib, ¿no estoy seguro de si funcionaría igual? – Ries

+0

Busqué en Google la fuente de gnosis y vi llamadas a getstate y setstate, así que creo que funcionará. – FogleBird

+0

Esto funcionó perfectamente para mí, gracias! – amirpc

3

Su clase puede implementar el método especial __getstate__ para devolver exactamente qué partes de una instancia quiere ser escamado.

Hay varias variantes posibles en que (aunque __getstate__ y su complementario opcional método __setstate__ son más general) - véase la página doc Python en línea para pickle, a la que ya he señalado más arriba, ya que es la única que documenta __getstate__.

+0

gracias. idealmente me gustaría solo tener que especificar lo que NO quiero recortar. – Ries

+1

@Ries, recorra todos los miembros (utilizando inspeccionar.obtener miembros, '__dict__' de la instancia, lo que sea) y elimine los que desee eliminar. No hay un método especial '__donotsavetheseones_', tienes que implementarlo como' __getstate__'. –

3

Esto podría ser una mejor solución, ya que permitirá un objeto creado a través de copy.deepcopy Todavía tiene un self.logger

def __getstate__(self): 
    d = self.__dict__.copy() 
    if 'logger' in d.keys() 
     d['logger'] = d['logger'].name 
    return d 

def __setstate__(self, d): 
    if 'logger' in d.keys(): 
     d['logger'] = logging.getLogger(d['logger']) 
    self.__dict__.update(d) 
Cuestiones relacionadas