Skip to content Skip to sidebar Skip to footer

Skip Numpy __new__ In Ndarray Subclass (or Possibly Overriding/defining Classes In C Or Cython)

Ultimate goal: have isinstance(MyClass(), np.ndarray) and issubclass(MyClass, np.ndarray) both return True without MyClass calling np.ndarray.__new__(). Let's say I've implemented

Solution 1:

I don't know if it is possible to fake isinstance and issubclass, but in the following approach you can define your class passing to np.ndarray.__new__ only the arguments that you want:

import numpy as np
class BlockingClass(np.ndarray):
    def __new__(cls, *args, **kwargs):
        ndarray_kw = ['shape', 'dtype',  'buffer' 'offset', 'strides', 'order']
        to_ndarray = {}
        to_myclass = {}
        for k,v in kwargs.items():
            if k not in ndarray_kw:
                to_myclass[k] = v
            else:
                to_ndarray[k] = v
        new = np.ndarray.__new__(cls, *args, **to_ndarray)
        for k,v in to_myclass.items():
            setattr(new, k, v)
        return new

    def __init__(self, *args, **kwargs):
        self.test = 1
        self.args = args
        self.kwargs = kwargs

Solution 2:

You can possibly fake the isinstance in Python, but you certainly cannot create a class that would work the same for the native code in numpy without calling its __new__.

I was thinking of everything complicated but, then realized that some functions you are calling might also return ndarray; if you want them completely replaced then you can monkeypatch the numpy module to have your class instead, this might be the only way; or replace ndarray with a module with a class with metaclass that has a subclass hook that will say that the original ndarray and your class are both instances of the same...

Or if only the isinstance is troubling, then do something really really dirty, and try

import __builtin__

_original_isinstance = __builtin__.isinstance
class FakeArray(object):
    pass

def isinstance(object, class_or_type):
    if _original_isinstance(object, tuple):
        if ndarray in class_or_type:
            class_or_type += (FakeArray,)

    else:
        if class_or_type is ndarray:
            class_or_type = (ndarray, FakeArray)

    return _original_isinstance(object, class_or_type)

__builtin__.isinstance = isinstance

Post a Comment for "Skip Numpy __new__ In Ndarray Subclass (or Possibly Overriding/defining Classes In C Or Cython)"