[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