# Python __rmul__() Magic Method

## 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:

1. The method `x.__mul__()` is not implemented in the first place, or
2. The method `x.__mul__()` is implemented but returns a `NotImplemented` 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: