You also need to implement __rmul__
. When the initial call to int.__mul__(7, v)
fails, Python will next try type(v).__rmul__(v, 7)
.
def __rmul__(self, lhs):
return self * lhs # Effectively, turn 7 * v into v * 7
As Rawing points out, you could simply write __rmul__ = __mul__
for this definition. __rmul__
exists to allow for non-commutative multiplication where simply deferring to __mul__
with the operands reversed isn't sufficient.
For instance, if you were writing a Matrix
class and wanted to support multiplication by a nested list, e.g.,
m = Matrix(...) # Some 2 x 2 matrix
n = [[1, 2], [3,4]]
p = n * m
Here, the list
class wouldn't know how to multiple a list by a Matrix
instance, so when list.__mul__(n, m)
fails, Python would next try Matrix.__rmul__(m, n)
. However, n * m
and m * n
are two different results in general, so Matrix.__rmul__(m, n) != Matrix.__mul__(m, n)
; __rmul__
has to do a little extra work to generate the right answer.