¿Cómo encurtirse?

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?