python阻止运算符调用

python阻止运算符调用,python,numpy,operator-overloading,operators,Python,Numpy,Operator Overloading,Operators,我有一个类CustomArray,类似于numpy.ndarray。它重载了一组算术运算符,如\uuuu add\uuuu、\uu mul\uuuu等。由于人们很可能会将其与numpy结合使用,我担心会不时调用numpy.ndarray运算符,而不是CustomArray。最糟糕的是,它们实际工作并产生一些不想要的结果 a = np.array([1, 2, 3]) b = CustomArray([1, 2, 3]) c = a + b # np.ndarray.__add__ will b

我有一个类
CustomArray
,类似于
numpy.ndarray
。它重载了一组算术运算符,如
\uuuu add\uuuu
\uu mul\uuuu
等。由于人们很可能会将其与numpy结合使用,我担心会不时调用
numpy.ndarray
运算符,而不是
CustomArray
。最糟糕的是,它们实际工作并产生一些不想要的结果

a = np.array([1, 2, 3])
b = CustomArray([1, 2, 3])
c = a + b  # np.ndarray.__add__ will be called!

有没有办法防止这种情况发生?所以解释器要么会引发错误,要么总是喜欢
CustomArray
操作符重载。

在NumPy 1.13中,有一个新的。此API是临时的,向后兼容性尚未得到保证

numpy.ndarray
将其运算符委托给numpy ufuncs,并且numpy ufuncs将委托给
\uuuuuuu array\uuuuunc
以实现ufunc行为(如果他们发现)。此操作的规则跳过
numpy.ndarray.\uuuu数组\uuufunc\uufunc
,因此,如果您实现自己的
\uuuuu数组\uufunc\uufunc
,则在将实例与numpy数组一起使用时,它将始终具有优先权

如果要禁用对象上的所有ufunc,可以在类上设置
\uuuuu数组\uuufunc\uuuu=None

class CustomArray(...):
    __array_ufunc__ = None
或者,如果您想要实现它,则签名是

def __array_ufunc__(self, ufunc, method, *inputs, **kwargs)
对于你感兴趣的案件

  • ufunc
    是ufunc对象(例如,
    numpy.add
    for
    +
  • 方法是
    “\uuuuu调用”
  • 输入
    是元组
    (左操作数、右操作数)
    ,和
  • kwargs
    为空
对于更高级的情况,
方法
输入
kwargs
可能不同,因此如果您不想处理这些情况,
返回NotImplemented

例如,如果要使用NumPy数组重载
+
,可以编写

def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
    if ufunc is not numpy.add:
        return NotImplemented
    if method != "__call__":
        return NotImplemented
    if kwargs:
        return NotImplemented
    return my_addition_logic(*inputs)

您还需要在NumPy 1.13中实现
\uuuuu add\uuuu

,这是新的。此API是临时的,向后兼容性尚未得到保证

numpy.ndarray
将其运算符委托给numpy ufuncs,并且numpy ufuncs将委托给
\uuuuuuu array\uuuuunc
以实现ufunc行为(如果他们发现)。此操作的规则跳过
numpy.ndarray.\uuuu数组\uuufunc\uufunc
,因此,如果您实现自己的
\uuuuu数组\uufunc\uufunc
,则在将实例与numpy数组一起使用时,它将始终具有优先权

如果要禁用对象上的所有ufunc,可以在类上设置
\uuuuu数组\uuufunc\uuuu=None

class CustomArray(...):
    __array_ufunc__ = None
或者,如果您想要实现它,则签名是

def __array_ufunc__(self, ufunc, method, *inputs, **kwargs)
对于你感兴趣的案件

  • ufunc
    是ufunc对象(例如,
    numpy.add
    for
    +
  • 方法是
    “\uuuuu调用”
  • 输入
    是元组
    (左操作数、右操作数)
    ,和
  • kwargs
    为空
对于更高级的情况,
方法
输入
kwargs
可能不同,因此如果您不想处理这些情况,
返回NotImplemented

例如,如果要使用NumPy数组重载
+
,可以编写

def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
    if ufunc is not numpy.add:
        return NotImplemented
    if method != "__call__":
        return NotImplemented
    if kwargs:
        return NotImplemented
    return my_addition_logic(*inputs)

您还需要实现类似的最近问题(但没有答案):不,没有。如果左边的操作数实现该方法,它首先被执行。@ JONRRAPEPE MB有一种方法来修改<代码> CustomArray <代码>,这样NUMPY会产生一些合理的错误消息。除非是这样,否则不会调用其他方法。最近类似的问题(但没有答案):不,没有。如果左边的操作数实现该方法,它首先被执行。@ JONRRAPEPE MB有一种方法来修改<代码> CustomArray <代码>,这样NUMPY会产生一些合理的错误消息。除非是这样,否则其他方法将不会被调用。由于某种原因无法使其工作,它是否只在我从np子类化时工作。ndarray?@DikobrAz:No,子类化
numpy。ndarray
不是一个明确的要求。出于某种原因无法使其工作,它是否只在我从np子类化时工作。ndarray?@DikobrAz:No,子类化
numpy.ndarray
不是一项具体要求。