[Python] pickle di una classe derivata
Simone Ziraldo
simone.ziraldo a gmail.com
Mer 5 Dic 2012 18:13:57 CET
On 05/dic/2012, at 10.05, Marco Giusti wrote:
> On Wed, Dec 05, 2012 at 12:04:54AM +0100, Simone Ziraldo wrote:
>> Ciao a tutti,
>>
>> il problema che ho è questo: quando faccio il pickle di una classe derivata di numpy.ndarray non mi salva gli attributi che ho definito io.
>> Un codice semplice che genera questo problema è questo:
>>
>> import pickle
>> import numpy
>>
>> class prova( numpy.ndarray ):
>> def __new__(cls,size):
>> return numpy.ndarray.__new__( cls, size )
>> def __init__(self,size ):
>> self.__size__ = size
>>
>> s = prova(2)
>>
>> f = open("prova.out", 'w')
>> pickle.dump(s,f)
>> f.close()
>>
>> f = open("prova.out", 'r')
>> obj = pickle.load(f)
>> f.close
>>
>> print obj.__size__
>>
>> e mi viene restituito questo errore:
>> AttributeError: 'prova' object has no attribute '__size__'
>
> >>> class prova2(numpy.ndarray):
> ... def __init__(self, size):
> ... numpy.ndarray.__init__(self, size)
> ... self.__size__ = size
> ... def __reduce__(self):
> ... t = numpy.ndarray.__reduce__(self)
> ... klass, args = t[:2]
> ... func, args = t[:2]
> ... return (reconstruct, (func, args, self.__size__)) + t[2:]
> ...
> >>> def reconstruct(f, args, size):
> ... o = f(*args)
> ... o.__size__ = size
> ... return o
> ...
> >>> p3 = pickle.loads(pickle.dumps(p2))
> >>> p3
> prova2([ 6.90286283e-310, 6.90286283e-310, 1.58101007e-322])
> >>> p3.__dict__
> {'__size__': 3}
> >>>
>
> la documentazione su pickle spiega tutto
Grazie!
Mi sono guardato la documentazione e mi sono rimasti dei dubbi.
Ad esempio non mi è ben chiaro quando nel dump decide di usare il metodo __reduce__ invece di __getstate__. La guida dice che usa __reduce__ "When the Pickler encounters an object of a type it knows nothing about", però ad esempio se faccio il dump di una classe nuova non usa __reduce__ ma __getstate__.
Ad esempio:
class trial():
def __reduce__(self):
print "Hello from reduce"
def __getstate__(self):
print "Hello from getstate"
pickle.loads(pickle.dumps( trial()))
stampa: Hello from getstate
Quindi, trial è un type che "conosce", mentre una classe derivata da numpy.ndarray (nell'esempio iniziale) è un type che non conosce...
Grazie,
Simone
Maggiori informazioni sulla lista
Python