Nuevo en python ... tengo la siguiente clave de clase, que extiende dict:

class Key( dict ):

    def __init__( self ):
        self = { some dictionary stuff... }

    def __getstate__(self):
        state = self.__dict__.copy()
        return state

    def __setstate__(self, state):
        self.__dict__.update( state )

Quiero guardar una instancia de la clase con sus datos usando pickle.dump y luego recuperar los datos usando pickle.load. Entiendo que se supone que debo cambiar de alguna manera el getstate y el setstate, sin embargo, no estoy del todo claro sobre cómo se supone que debo hacer eso ... ¡cualquier ayuda sería muy apreciada!

1
ElfsЯUs 23 feb. 2012 a las 11:52

1 respuesta

La mejor respuesta

Escribí una subclase de dict que hace esto aquí está.

class AttrDict(dict):
    """A dictionary with attribute-style access. It maps attribute access to
    the real dictionary.  """
    def __init__(self, *args, **kwargs):
        dict.__init__(self, *args, **kwargs)

    def __getstate__(self):
        return self.__dict__.items()

    def __setstate__(self, items):
        for key, val in items:
            self.__dict__[key] = val

    def __repr__(self):
        return "%s(%s)" % (self.__class__.__name__, dict.__repr__(self))

    def __setitem__(self, key, value):
        return super(AttrDict, self).__setitem__(key, value)

    def __getitem__(self, name):
        return super(AttrDict, self).__getitem__(name)

    def __delitem__(self, name):
        return super(AttrDict, self).__delitem__(name)

    __getattr__ = __getitem__
    __setattr__ = __setitem__

    def copy(self):
        return AttrDict(self)

Básicamente, convierte el estado en una tupla básica y lo recupera para deshacerlo.

Pero tenga en cuenta que debe tener un archivo fuente original disponible para deshacerse. El decapado no salva realmente la clase en sí, solo el estado de la instancia. Python necesitará la definición de clase original para volver a crear.

3
Keith 23 feb. 2012 a las 11:57
¡Eso es fantástico! ¡Gracias Keith! Sin embargo, sigo recibiendo el siguiente error cuando intento obj = pickle.load y luego imprimo obj.self: return super (Key, self) .__ getitem __ (name) KeyError: 'self'
 – 
ElfsЯUs
23 feb. 2012 a las 12:04
Si solo imprimo obj, obtengo la clave de salida extraña ({}) en lugar de {} ... ¿alguna idea de lo que podría estar pasando aquí?
 – 
ElfsЯUs
23 feb. 2012 a las 12:04
ElfsRUs: Esto último se debe al método repr . Keith lo diseñó específicamente para que se vea así. Puede cambiarlo a return "%s" % (dict.__repr__(self),) si desea que se vea como {}. En cuanto al primer problema, ¿podría publicar el código que utilizó para obtener ese rastreo?
 – 
David Robinson
23 feb. 2012 a las 12:15
Gracias por la aclaración, estoy haciendo lo siguiente: key = pickle.load (open (sys.argv [2], "rb")) print key.self.
 – 
ElfsЯUs
23 feb. 2012 a las 12:43
¿Cuál es el código que usó para encurtir el objeto en primer lugar?
 – 
David Robinson
23 feb. 2012 a las 21:18