[Numpy-discussion] Trouble subclassing ndarray
Sebastian Berg
sebastian at sipsolutions.net
Fri Apr 10 03:13:26 EDT 2015
On Do, 2015-04-09 at 21:30 -0700, Elliot wrote:
> 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__ )
>
You have a typo in your __array_finalize__ it misses the last
underscore, that is probably why it is never called. About the infinite
recursion, not sure on first sight.
>
> 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.
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion at scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20150410/d28210eb/attachment.sig>
More information about the NumPy-Discussion
mailing list