I'm working as a free time project on a vector class in Python, to test myself. People with enough math background know that a vector can be multiplied by a scalar; 2 * (1, 2) = (2 * 1, 2 * 2) = (2, 4).
This is simple enough to do in, say, C#. public static operator *(int scalar, Vector vector)
and go on to define it. But when I try to do the most obvious route in Python, it throws a TypeError at me:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for *: 'int' and 'Vector'
This is also raised when I reverse the order of the operands to Vector * scalar
.
Now, I know that, in Python, iterables such as strings can be multiplied: e.g. "abc" * 2 yields "abcabc". My question is: is this only an inherent feature of the language, or is there a way to write multi-type operators?
The code:
class Vector:
def __init__(self, *contents):
self.__c = contents
def __iter__(self):
return iter(self.__c)
def __add__(u, v):
exceptIfUnequal(u, v, "add") # <-- This is just a method that will raise an error if the vectors are unequal, it's unimportant to us
return Vector(*[a + b for a, b in zip(u, v)])
def __sub__(u, v):
exceptIfUnequal(u, v, "subtract")
return a + (-b)
def __neg__(u):
return Vector(-a for a in u)
def __mult__(k, u):
return Vector(*[k * a for a in u])
#I'm aware that logistically, k and u will need to be reversed if I want to reverse the order
def __len__(u):
return len(u.__c)
def __str__(self):
s = "<" + "{}, " * (len(self.__c) - 1) + "{}>"
return s.format(*self.__c)
So is there anything I can do to make this work? Or is it simply impossible?
EDIT: Wouldn't you know it, it was a silly mistake. The proper Python multiplication is __mul__
, not - as I had written - __mult__
-- with a t. But even more particularly, the item I wanted was __rmul__
, which allows me to multiply in scalar * vector order.