python - 跳过 ndarray 子类中的 numpy __new__ (或者可能覆盖/定义 C 或 cython 中的类)

标签 python class numpy subclass cython

最终目标:让 isinstance(MyClass(), np.ndarray)issubclass(MyClass, np.ndarray) 均返回 True 没有 MyClass 调用 np.ndarray.__new__()

<小时/>

假设我已经实现了 numpy.ndarray 的所有方法,并且我想对其进行设置,以便它能够通过 ndarray<的 isinstance 检查,但我希望它实际上从 ndarray 调用 __new__

最初,我在想这样的事情:

import numpy as np
class BlockingClass(np.ndarray):
    def __new__(cls, *args, **kwargs):
        return object.__new__(cls)

不幸的是,尝试实例化 Dummy() 会产生此错误,表明它不安全:

TypeError: object.__new__(Dummy) is not safe, use numpy.ndarray.__new__()

如果它是对象的子类,则此方法有效:

class BlockingClass2(object):
    def __new__(cls, *args, **kwargs):
        return object.__new__(cls)

BlockingClass2() # No error

我很确定这是因为 ndarray 是一个 C 类,所以我正在考虑在 C 类(或者最好是 Cython 类)中重写它,并使用多重继承来无需调用 __new__ 即可进行类型检查。所以我的类(class)是:

类 MyClass(BlockingClass, np.ndarray): 通过

其中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

但是,当 BlockingClass 像上面那样通过定义 __new__ 的对象通过多重继承进行子类化时,该 __new__ 方法仍然会被调用。如果我无法在 Cython 中执行此操作,那么我需要定义一个基类,通过多重继承跳过 ndarray 的 __new__ 的最少 C 代码量是多少?也许我可以导入一个函数来实例化该类,而无需升级 mro?

最佳答案

我不知道是否可以伪造 isinstanceissubclass,但在以下方法中,您可以定义传递给 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():
            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

关于python - 跳过 ndarray 子类中的 numpy __new__ (或者可能覆盖/定义 C 或 cython 中的类),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18284660/

相关文章:

java - 创建具有多个类的对象

python - numpy(.ma) 数组 : Number of values since last value change?

python - 使用 .apply、.applymap、.groupby 转换 Pandas DataFrame 中的异常值

python - 将大量数据附加到表 (HDF5) 数据库,其中 database.numcols != newdata.numcols?

python - 如何从 tensorflow 数据集中选择特定列?

Python selenium lib 未在 Windows 上安装

python - PyCharm 可以列出项目中的所有 Python 错误吗?

python - 如何在python中用一个单词替换多个单词?

C++ 类模板未定义对函数的引用

java - 使用点类计算圆的面积和周长