Определяемый пользователем метод __mul__ не является коммутативным - PullRequest
23 голосов
/ 20 августа 2011

Я написал класс для представления векторов в Python (как упражнение), и у меня возникли проблемы с расширением встроенных операторов.

Я определил __mul__ метод для векторного класса. Проблема в том, что в выражении x * y интерпретатор вызывает метод __mul__ для x, а не y.

Итак, vector(1, 2, 3) * 2 возвращает вектор <2, 4, 6> точно так же, как и должен; но 2 * vector(1, 2, 3) создает TypeError, потому что встроенный класс int не поддерживает умножение на мои пользовательские векторы.

Я мог бы решить эту проблему, просто написав новую функцию умножения

def multiply(a, b):
    try:
        return a * b
    except TypeError:
        return b * a

но для этого потребуется переопределить каждую функцию, которую я хочу использовать с моими пользовательскими классами.

Есть ли способ заставить встроенную функцию обрабатывать это правильно?

Ответы [ 2 ]

28 голосов
/ 20 августа 2011

Если вы хотите коммутативность для разных типов , вам нужно реализовать __rmul__(). Если он реализован, он вызывается, как и все __r*__() специальные методы, если в противном случае операция вызвала бы TypeError. Помните, что аргументы поменялись местами:

class Foo(object):
    def __mul_(self, other):
        ''' multiply self with other, e.g. Foo() * 7 '''
    def __rmul__(self, other):
        ''' multiply other with self, e.g. 7 * Foo() '''
3 голосов
/ 20 августа 2011

Я полагаю, вы ищете __rmul__

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...