Stuart Reynolds
2016-12-14 19:45:07 UTC
I'm trying to subclass an NDArray as shown here:
https://docs.scipy.org/doc/numpy/user/basics.subclassing.html
My problem is that when I save the new class' state with pickle, the new
attributes are lost. I don't seem to be able to override __getstate__ or
__setstate__ to achieve this?
Is it possible to allow new state to serialized when overriding an NDArray?
In my example below, __setstate__ gets called by pickle but not
__getstate__.
In the final line, a RealisticInfoArray has been deserialized, but it has
no .info attribute.
----
import cPickle as pickle
import numpy as np
class RealisticInfoArray(np.ndarray):
def __new__(cls, arr, info):
obj = np.asarray(arr).view(cls)
obj.info = info
return obj
def __array_finalize__(self, obj):
if obj is None: return
self.info = getattr(obj,"info",None)
def __setstate__(self, *args):
print "SET"
return np.ndarray.__setstate__(self,*args)
def __getstate__(self):
print "GET"
assert False, "EXPLODE"
return np.ndarray.__getstate__(self)
arr = np.zeros((2,3), int)
arr = RealisticInfoArray(arr, "blarg")
print arr.info
arr2 = pickle.loads(pickle.dumps(arr))
print arr2.info # no .info attribute!
https://docs.scipy.org/doc/numpy/user/basics.subclassing.html
My problem is that when I save the new class' state with pickle, the new
attributes are lost. I don't seem to be able to override __getstate__ or
__setstate__ to achieve this?
Is it possible to allow new state to serialized when overriding an NDArray?
In my example below, __setstate__ gets called by pickle but not
__getstate__.
In the final line, a RealisticInfoArray has been deserialized, but it has
no .info attribute.
----
import cPickle as pickle
import numpy as np
class RealisticInfoArray(np.ndarray):
def __new__(cls, arr, info):
obj = np.asarray(arr).view(cls)
obj.info = info
return obj
def __array_finalize__(self, obj):
if obj is None: return
self.info = getattr(obj,"info",None)
def __setstate__(self, *args):
print "SET"
return np.ndarray.__setstate__(self,*args)
def __getstate__(self):
print "GET"
assert False, "EXPLODE"
return np.ndarray.__getstate__(self)
arr = np.zeros((2,3), int)
arr = RealisticInfoArray(arr, "blarg")
print arr.info
arr2 = pickle.loads(pickle.dumps(arr))
print arr2.info # no .info attribute!