Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

User defined __mul__ method is not commutative

I wrote a class to represent vectors in Python (as an exercise) and I'm having problems with extending the built-in operators.

I defined a __mul__ method for the vector class. The problem is that in the expression x * y the interpreter calls the __mul__ method of x, not y.

So vector(1, 2, 3) * 2 returns a vector <2, 4, 6> just like it should; but 2 * vector(1, 2, 3) creates a TypeError because the built-in int class does not support multiplication by my user-defined vectors.

I could solve this problem by simply writing a new multiplication function

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

but this would require redefining every function that I want to use with my user-defined classes.

Is there a way to make the built-in function handle this correctly?

like image 392
smackcrane Avatar asked Aug 20 '11 03:08

smackcrane


People also ask

What is __ MUL __ in Python?

The Python __mul__() method is called to implement the arithmetic multiplication operation * . For example to evaluate the expression x * y , Python attempts to call x. __mul__(y) .

What is the __ str __ method in Python?

Python __str__() This method returns the string representation of the object. This method is called when print() or str() function is invoked on an object. This method must return the String object.

What is __ add __ in Python?

The __add__() method in Python specifies what happens when you call + on two objects. When you call obj1 + obj2, you are essentially calling obj1. __add__(obj2). For example, let's call + on two int objects: n1 = 10.


1 Answers

If you want commutativity for different types you need to implement __rmul__(). If implemented, it is called, like all __r*__() special methods, if the operation would otherwise raise a TypeError. Beware that the arguments are swapped:

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() ''' 
like image 197
pillmuncher Avatar answered Sep 21 '22 07:09

pillmuncher