请考虑以下代码段:
import numpy as np
class MyClass:
def __rsub__(self, other):
print(type(other), other)
obj = MyClass()
arr = np.ones(3)
arr - obj
我希望它能打印<class 'numpy.ndarray'> [1. 1. 1.]
。
但实际上,似乎每个元素都调用__rsub__
:
<class 'float'> 1.0
<class 'float'> 1.0
<class 'float'> 1.0
是否可以告诉numpy我想要 first 行为,即将 entire 减法委派给MyClass
? / p>
答案 0 :(得分:2)
在NumPy 1.13+上,您可以使用NumPy特定的钩子来执行此操作,但是通常无法使S[5]
击败__rsub__
方法。
__sub__
无法处理该操作,则尝试 __rsub__
,但是左操作数可以处理该操作。 NumPy数组的__sub__
将接受任何RHS并执行广播减法。对象的__sub__
仅对广播减法中的各个操作起作用。
在非常有限的情况下,首先尝试__rsub__
,即RHS的类别是LHS的类别的子类别。从技术上讲,您可以细分__rsub__
的子类,但这会带来很多的额外负担,而对于numpy.ndarray
或其他子类仍然没有任何作用。
无法说“我希望我的numpy.matrix([[1]]) - obj
赢得一切”。它不存在,并且存在也没有意义,因为如果您试图减去两个都想声明其方法的对象会击败一切,那会发生什么?
这就是一般情况。但是,专门针对NumPy,您可以使用__rsub__
委托的机制。
NumPy数组将numpy.ndarray.__sub__
委托给NumPy ufunc机制。那里有很多奇怪的自定义选项,但是我们对一个特定选项的特定用法感兴趣:通过在类级别将__array_ufunc__
设置为__sub__
,可以声明一个与ufunc不兼容的类。这意味着所有NumPy运算符重载都将返回None
,让您的类处理该操作。这会影响 all 运算符和更多的东西,但是您可能会想要:
NotImplemented
如果您想要的东西比阻止所有ufunc更具针对性,则可以实现实际的class MyClass:
__array_ufunc__ = None
def __rsub__(self, other):
print(type(other), other)
方法,并处理ufunc减法且类的实例为RHS的情况:
__array_ufunc__