2012-06-28 26 views
6

Quiero definir una clase que pueda poblarse leyendo de los datos serializados de otra instancia. Aquí está el código simplificado:¿Cómo inicializar una instancia usando pickle()?

class MyClass(list): 

    def __init__(self,**kwargs): 
     if kwargs.has_key('fdata'): 
      f = open(kwargs['fdata'],'r') 
      self = pickle.load(f) 
      print len(self) #prints 320   
      f.close()    

    ... 

a = MyClass(fdata='data.dat') 
print len(a) #prints 0 

Ésta es la salida obtengo:

320 
0 

El problema que tengo es que la instancia devuelta siempre está vacío, a pesar de que soy capaz de leer todos los elementos en el interior __init__() ¿Qué puede estar causando esto?

Respuesta

4

Asignación a self dentro de un método simplemente vuelve a vincular el nombre local self a un objeto diferente. Las asignaciones a nombres vacíos en Python nunca pueden modificar ningún objeto; solo vuelven a vincular nombres.

¿Por qué no usar la una nueva clase recta de avance

with open("data.dat") as f: 
    a = pickle.load(f) 

en lugar de construir? Si no te gusta esto, envuelve esto en una función, pero no es tan útil poner este código en __init__().

Hay otras formas de lograr el mismo efecto. Probablemente la mejor manera de lograr exactamente lo que está intentando es sobrescribir __new__() en lugar de __init__() - __new__() se llama antes de se construye la nueva instancia, por lo que simplemente puede devolver la instancia no modificada en lugar de tener que modificar una ya construida.

3

self es una variable local normal en Python. No puede usar self = other para hacer que un objeto "se convierta" en algo diferente, solo reasignará el local. Vas a tener que restaurar los atributos de uno-a-uno, o usar algo como: (. No he probado la última línea, bien podría hacer que sus gatitos explotan)

self.__dict__ = pickle.load(f).__dict__ 

+0

Asignar a '__dict__' para copiar el estado del objeto funciona en el caso (común) que deriva de' objeto' y no define '__slots__'. –

+1

'self .__ dict __. Update()' podría ser una opción "más segura", pero podría quedar con cosas que se eliminaron de los datos encurtidos por una buena razón ... –

Cuestiones relacionadas