Quiero que mi clase implemente funciones de Guardar y Cargar que simplemente hacen un pickle de la clase. Pero aparentemente no puedes usar “yo” de la manera que se muestra a continuación. ¿Cómo puedes hacer esto?
self = cPickle.load(f) cPickle.dump(self,f,2)
Esto es lo que terminé haciendo. Actualizar el __dict__
significa que mantenemos las nuevas variables de miembro que agrego a la clase y solo actualizamos las que estaban allí cuando el objeto fue pickle por última vez. Parece lo más sencillo, a la vez que mantiene el código de guardado y carga dentro de la propia clase, por lo que el código de llamada solo hace un objeto.
def load(self): f = open(self.filename, 'rb') tmp_dict = cPickle.load(f) f.close() self.__dict__.update(tmp_dict) def save(self): f = open(self.filename, 'wb') cPickle.dump(self.__dict__, f, 2) f.close()
La parte del volcado debería funcionar como usted sugirió. para la parte de carga, puede definir un @classmethod que carga una instancia de un archivo dado y la devuelve.
@classmethod def loader(cls,f): return cPickle.load(f)
entonces la persona que llama haría algo como:
class_instance = ClassName.loader(f)
Si desea que su clase se actualice desde un pickle guardado … prácticamente debe usar __dict__.update
, como lo ha hecho en su propia respuesta. Sin embargo, es como si un gato persiguiera su cola … mientras le pide a la instancia que esencialmente se “reinicie” con el estado anterior.
Hay un ligero cambio en tu respuesta. De hecho, puedes escabullirte.
>>> import dill >>> class Thing(object): ... def save(self): ... return dill.dumps(self) ... def load(self, obj): ... self.__dict__.update(dill.loads(obj).__dict__) ... >>> t = Thing() >>> tx = 1 >>> _t = t.save() >>> tx = 2 >>> tx 2 >>> t.load(_t) >>> tx 1
Utilicé loads
y dumps
lugar de load
y dump
porque quería que la salmuera se guardara en una cadena. Usar load
y dump
en un archivo también funciona. Y, en realidad, puedo usar dill
para encurtir una instancia de clase en un archivo, para su uso posterior … incluso si la clase está definida interactivamente. Continuando desde arriba …
>>> with open('self.pik', 'w') as f: ... dill.dump(t, f) ... >>>
luego parando y reiniciando …
Python 2.7.10 (default, May 25 2015, 13:16:30) [GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import dill >>> with open('self.pik', 'r') as f: ... t = dill.load(f) ... >>> tx 1 >>> print dill.source.getsource(t.__class__) class Thing(object): def save(self): return dill.dumps(self) def load(self, obj): self.__dict__.update(dill.loads(obj).__dict__) >>>
Estoy usando dill
, que está disponible aquí: https://github.com/uqfoundation
Hay un ejemplo de cómo encurtir una instancia aquí, en los documentos . (Busque el ejemplo “TextReader”). La idea es definir los métodos __getstate__
y __setstate__
, que le permiten definir qué datos deben ser decapados, y cómo usar esos datos para volver a crear una instancia del objeto.
¿Qué tal si escribe una clase llamada Serializable que implementaría el volcado y la carga y haría que su clase heredara de ella?