Syntax
object.__rmul__(self, other)
The Python __rmul__()
method implements the reverse multiplication operation that is multiplication with reflected, swapped operands. So, when you call x * y
, Python attempts to call x.__mul__(y)
. Only if the method is not implemented on the left operand, Python attempts to call __rmul__
on the right operand and if this isn’t implemented either, it raises a TypeError
.
We call this a “Dunder Method” for “Double Underscore Method” (also called “magic method”). To get a list of all dunder methods with explanation, check out our dunder cheat sheet article on this blog.
Python __mul__ vs __rmul__
Say, you want to calculate the *
operation on two custom objects x
and y
:
print(x * y)
Python first tries to call the left object’s __mul__()
method x.__mul__(y)
. But this may fail for two reasons:
- The method
x.__mul__()
is not implemented in the first place, or - The method
x.__mul__()
is implemented but returns aNotImplemented
value indicating that the data types are incompatible.
If this fails, Python tries to fix it by calling the y.__rmul__()
for reverse multiplication on the right operand y
.
If the reverse multiplication method is implemented, Python knows that it doesn’t run into a potential problem of a non-commutative operation. If it would just execute y.__mul__(x)
instead of x.__mul__(y)
, the result would be wrong because the operation may be non-commutative when defined as a custom operation. That’s why y.__rmul__(x)
is needed.
So, the difference between x.__mul__(y)
and x.__rmul__(y)
is that the former calculates x * y
whereas the latter calculates y * x
— both calling the respective method defined on the object x
.
You can see this in effect here where we attempt to call the operation on the left operand x
—but as it’s not implemented, Python simply calls the reverse operation on the right operand y
.
class Data_1: pass class Data_2: def __rmul__(self, other): return 'called reverse *' x = Data_1() y = Data_2() print(x * y) # called reverse *
References: