I have a vector class:
class Vector:
def __init__(self, x, y):
self.x, self.y = x, y
def __str__(self):
return '(%s,%s)' % (self.x, self.y)
def __add__(self, n):
if isinstance(n, (int, long, float)):
return Vector(self.x+n, self.y+n)
elif isinstance(n, Vector):
return Vector(self.x+n.x, self.y+n.y)
which works fine, i.e. I can write:
a = Vector(1,2)
print(a + 1) # prints (2,3)
However if the order of operation is reversed, then it fails:
a = Vector(1,2)
print(1 + a) # raises TypeError: unsupported operand type(s)
# for +: 'int' and 'instance'
I understand the error: the addition of an int
object to an Vector
object is undefined because I haven't defined it in the int
class. Is there a way to work around this without defining it in the int
(or parent of int
) class?
The __add__ method is used to implement addition operation. In Python, numbers are not primitive literals but objects. The num + 4 expression is equivalent to num. __add__(4) .
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) .
The normal way to add functionality (methods) to a class in Python is to define functions in the class body. There are many other ways to accomplish this that can be useful in different situations. The method can also be defined outside the scope of the class.
You need to also define __radd__
Some operations do not necessarily evaluate like this a + b == b + a and that's why Python defines the add and radd methods.
Explaining myself better: it supports the fact that "int" does not define a +
operation with class Vector
instances as part of the operation. Therefore vector + 1 is not the same as 1 + vector.
When Python tries to see what the 1.__add__
method can do, an exception is raised. And Python goes and looks for Vector.__radd__
operation to try to complete it.
In the OP's case the evaluation is true and suffices with __radd__ = __add__
class Vector(object):
def __init__(self, x, y):
self.x, self.y = x, y
def __str__(self):
return '(%s,%s)' % (self.x, self.y)
def __add__(self, n):
if isinstance(n, (int, long, float)):
return Vector(self.x+n, self.y+n)
elif isinstance(n, Vector):
return Vector(self.x+n.x, self.y+n.y)
__radd__ = __add__
a = Vector(1, 2)
print(1 + a)
Which outputs:
(2,3)
The same applies to all number-like operations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With