На NumPy 1.13+ вы можете сделать это с помощью специфических для NumPy хуков, но в целом вы не можете использовать __rsub__
beat __sub__
методы.
__rsub__
если левый операнд __sub__
не может обработать операцию, но левый операнд может обрабатывать эту операцию. __sub__
массива NumPy примет любую RHS и выполнит широковещательное вычитание. __rsub__
вашего объекта вступает в игру только для отдельных операций в транслируемом вычитании.
Существует один очень ограниченный случай, когда сначала проверяется __rsub__
, если класс RHS является подклассомкласс LHS. Технически вы можете подкласс numpy.ndarray
, но это будет с много дополнительного багажа и все равно ничего не делать для numpy.matrix([[1]]) - obj
или других подклассов.
Нет никакого способа сказать "яхочу, чтобы мой __rsub__
победил все ". Его не существует, и для него не будет смысла существовать, потому что что произойдет, если вы попытаетесь вычесть два объекта, которые оба хотят объявить, что их метод бьет все?
Так вотобщий случай. Тем не менее, специально для NumPy можно подключиться к механизмам, которым делегируется numpy.ndarray.__sub__
.
Делегат массивов NumPy __sub__
механизму NumPy ufunc . Там есть куча странных опций настройки, но нас интересует конкретное использование одной конкретной опции: установив __array_ufunc__
на None
на уровне класса, вы можете объявить класс, несовместимый сufuncs. Это означает, что все перегрузки оператора NumPy вернут NotImplemented
, что позволяет вашему классу обрабатывать операцию. Это влияет на все операторов и кучу других вещей, но таким образом, что вы, вероятно, захотите:
class MyClass:
__array_ufunc__ = None
def __rsub__(self, other):
print(type(other), other)
Если вы хотите что-то более целевое, чем блокирование всех ufuncs, вы можете реализовать фактический__array_ufunc__
метод и просто обработайте случай, когда ufunc вычитание и экземпляр вашего класса RHS:
class MyClass:
def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
if ufunc is not numpy.subtract:
return NotImplemented
if method != '__call__':
return NotImplemented
if len(inputs) != 2 or inputs[1] is not self:
return NotImplemented
if kwargs:
return NotImplemented
return self.__rsub__(inputs[0])
def __rsub__(self, other):
print(type(other), other)