Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overiding __mul__ in two dimensional vector class to preserve commutivity

Tags:

python

I have defined the following class:

class Point(object):

    def __repr__(self):
        return "("+str(self.x)+","+str(self.y)+")"

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, point):
        return Point(self.x+point.x,self.y+point.y)

    def __sub__(self, point):
        return Point(self.x-point.x,self.y-point.y)

    def __mul__(self, num):
         return Point(num*self.x,num*self.y)

    def length(self):
        return (self.x**2 + self.y**2)**.5

And the following code works:

x = Point(1,2)
y = Point(1,3)
print x+y
print (y+x)
print (x-y)
print (y-x)
print y*3

with output:

(2,5)
(2,5)
(0,-1)
(0,1)
(3,9)

But this does not:

print 3*y

It gives the following error:

----> 1 print 3*y
TypeError: unsupported operand type(s) for *: 'int' and 'Point'

Which is because the point class is being fed into the int mul function, I'm assuming. How can I keep the definition of point contained in the Point class and still have 3*y return the same as y*3?

like image 508
sakurashinken Avatar asked Jan 06 '17 19:01

sakurashinken


1 Answers

3 * y 

We have an int instance on the left side, and a Point instance on the right. Point is not a subclass of int. In this situation, int.__mul__ class gets the first chance at this operation, and Point.__mul__ gets no say in the matter.

You'll have to implement Point.__rmul__ on your class to handle the case.

like image 95
wim Avatar answered Nov 15 '22 06:11

wim