I would like to add a property (.csys
) to a subclass of numpy.ndarray:
import numpy as np
class Point(np.ndarray):
def __new__(cls, arr, csys=None):
obj = np.asarray(arr, dtype=np.float64).view(cls)
obj._csys = csys
return obj
def __array_finalize__(self, obj):
if obj is None: return
self._csys = getattr(obj, '_csys', None)
@property
def csys(self):
print('Getting .csys')
return self._csys
@csys.setter
def csys(self, csys):
print('Setting .csys')
self._csys = csys
However, when I run this test code:
pt = Point([1, 2, 3])
pt.csys = 'cmm'
print("pt.csys:", pt.csys)
# Pickle, un-pickle, and check again
import pickle
pklstr = pickle.dumps(pt)
ppt = pickle.loads(pklstr)
print("ppt.csys:", ppt.csys)
it appears that the attribute cannot be pickled:
Setting .csys
Getting .csys
pt.csys: cmm
Getting .csys
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
C:\Rut\Vanes\bin\pointtest.py in <module>()
39 ppt = pickle.loads(pklstr)
40
---> 41 print("ppt.csys:", ppt.csys)
C:\Rut\Vanes\bin\point.py in csys(self)
15 def csys(self):
16 print('Getting .csys')
---> 17 return self._csys
18
19 @csys.setter
AttributeError: 'Point' object has no attribute '_csys'
I tried doing the same thing without using decorators (e.g. defining get_csys()
and set_csys()
, plus csys = property(__get_csys, __set_csys)
, but had the same result with that.
I'm using numpy 1.13.3 under Python 3.6.3