本文介绍了在ndarray子类中跳过numpy __new__(或者可能覆盖/定义C或cython中的类)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 终极目标: MyClass 调用 np.ndarray .__ new __()。 我已经实现了所有的 numpy.ndarray 并且我想设置它,以便它将通过 isinstance 检查 ndarray ,但我不要实际从 ndarray 调用 __ new __ $ c>。 最初,我在想这样的: import numpy as np class BlockingClass(np.ndarray): def __new __(cls,* args,** kwargs): return object .__ new __(cls)$ b $不幸的是,试图实例化 Dummy()会产生这个错误关于它不安全: TypeError:object .__ new __(Dummy)不安全,使用numpy.ndarray .__ new __ 如果它是一个子类对象的类,它会工作: class BlockingClass2(object): def __new __(cls,* args,** kwargs): return object .__ new __(cls) BlockingClass2()#没有错误 我确定这是因为 ndarray 是一个C类,所以我想在C类(或者,最好是一个Cython类)重写它,并使用多继承来获得typecheck工作,而不调用 __ new __ 。所以我的类将是: class MyClass(BlockingClass,np.ndarray): pass 其中 BlockingClass 将是c定义的函数。我真的更喜欢在Cython这样做,但我不知道如何让它工作。我试过: cdef class BlockingClass: def __new __(cls,* args,** kwargs) : return object .__ new __(cls) 但这会产生相同的不安全错误以及 __ cinit __ 。 cdef class BlockingClass: def __cinit __(self,* args,** kwargs):#do stuff return self b $ b 但是,当 BlockingClass 是使用定义 __ new __ 仍然调用 __ new __ 方法。如果我不能在Cython中做到这一点,那么我需要定义一个通过多重继承跳过 ndarray ' __ new __ ?也许我可以导入一个函数来实例化类,而不需要上升mro?解决方案我不知道是否可能假冒 isinstance 和 issubclass ,但是在下面的方法中你可以定义你的类传递给 np.ndarray .__ new __ 只有您想要的参数: 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():如果k不在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 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 all the methods of numpy.ndarray and I want to set it up so that it will pass isinstance checks for ndarray, but I don't want it to actually call __new__ from ndarray.Initially, I was thinking of something like this:import numpy as npclass BlockingClass(np.ndarray): def __new__(cls, *args, **kwargs): return object.__new__(cls)Unfortunately, trying to instantiate Dummy() yields this error about it not being safe:TypeError: object.__new__(Dummy) is not safe, use numpy.ndarray.__new__()This works if it's a class that subclasses object:class BlockingClass2(object): def __new__(cls, *args, **kwargs): return object.__new__(cls)BlockingClass2() # No errorI'm pretty sure that it's because ndarray is a C class, so I was thinking of overriding it in a c-class (or, preferably, a Cython class) and using multiple inheritance to get the typecheck to work without calling __new__. So my class would be:class MyClass(BlockingClass, np.ndarray): passwhere BlockingClass would be the c-defined function. I'd really prefer to do this in Cython instead, but I can't figure out how to get it to work. I've tried doing:cdef class BlockingClass: def __new__(cls, *args, **kwargs): return object.__new__(cls)but this generates the same 'unsafe' error as well as with __cinit__.cdef class BlockingClass: def __cinit__(self, *args, **kwargs): # do stuff return selfBut, when BlockingClass is subclassed with multiple inheritance like above with an object that defines __new__, that __new__ method is still called. If I can't do this in Cython, what's the minimal amount of C code I would need to define a baseclass that, through multiple inheritance, would skip ndarray's __new__? Maybe I can cimport a function to instantiate the class without going up the mro? 解决方案 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 npclass 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 这篇关于在ndarray子类中跳过numpy __new__(或者可能覆盖/定义C或cython中的类)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-30 00:17