[Numpy-discussion] Trouble subclassing ndarray
Elliot
permafacture at gmail.com
Fri Apr 10 00:30:14 EDT 2015
Hi all,
Sorry if this is the wrong forum for a question like this.
I'm trying to create an object with multiple inheritance, one of which is
from numpy.ndarray. The other gives it cacheable properties and defines a
__getattr__ to deliver the cached properties. The initial instantiation is
successful, but ufuncs and slices cause an infinite recursion where the
__getattr__ function is used but the _cacheable attribute is not set (ie:
from __init__ )
I am using docs.scipy.org/doc/numpy/user/basics.subclassing.html as a
reference.
Here is code that shows my problem (python 2.7, numpy 1.8.2)
=====================
from __future__ import print_function
import numpy as np
class Cacheable(object):
def __init__(self,*args,**kwargs):
self._cacheable = {}
def __getattr__(self,key):
print("getting %s"%key)
if key in self._cacheable:
print(" found it")
self._cacheable[key]()
return self.__dict__[key] #if chache function does't update
# data you're going to have a bad time
else:
raise AttributeError
def _clear(self):
'''clears derived properties'''
for key in self._cacheable:
if key in self.__dict__:
del self.__dict__[key]
class BaseGeometry(np.ndarray,Cacheable):
'''Numpy array with extra attributes that are cacheable arrays'''
def __new__(cls,input_array,dtype=np.float64,*args,**kwargs):
# Input array is an already formed ndarray instance
# We first cast to be our class type
obj = np.asarray(input_array,dtype=dtype).view(cls)
# Finally, we must return the newly created object:
return obj
def __init__(self,dims=None,dtype=np.float64,readonly=True):
#TODO: sort through args and kwargs to make better
self.readonly=readonly
if readonly:
self.flags.writeable=False
self.dims=dims
self._dtype = dtype
Cacheable.__init__(self)
def writeable_copy(self):
ret = np.copy(self)
ret.flags.writeable = True
return ret
def __array_finalize_(self,obj):
#New object, will be created in __new__
print("array_finalize")
if obj is None: return
# created from slice or template
print("finalizing slice")
self._cacheable = getattr(obj, '_cacheable', None)
if __name__ == "__main__":
n = 5
test = BaseGeometry(np.random.randint(-25,25,(n,2)))
print("this works:",test._cacheable)
broken = test[1:4] #interestingly, no problem here
print(broken) #infinite recursion
===================
array_finalize is never called.
output is:
this works: {}
getting _cacheable
getting _cacheable
getting _cacheable
[and on and on]
getting _cacheable
getting _cacheable
<repr(<__main__.BaseGeometry at 0x7fa42e2921b8>) failed: RuntimeError:
maximum recursion depth exceeded while calling a Python object>
--
View this message in context: http://numpy-discussion.10968.n7.nabble.com/Trouble-subclassing-ndarray-tp40176.html
Sent from the Numpy-discussion mailing list archive at Nabble.com.
More information about the NumPy-Discussion
mailing list