There's nothing magical about arithmetic operators
For example:
>>> my_numbers * 2
returns the same as:
>>> my_numbers.__mul__(2)
`.__mul__()` is the special method which defines what multiplication using * does
But, this can be misleading. There's a bit more happening…
For example, you can achieve the same multiplication of a list by reversing the operands:
>>> 2 * my_numbers
[2, 4, 6, 2, 4, 6]
But, this is _not_ the same as calling `.__mul__()` directly
Note there's a space between the `2` and `.__mul__()` to avoid syntax issues
This returns `NotImplemented` and not the same result as
`2 * my_numbers`
The result from `2 * my_numbers` is actually returned by:
`my_numbers.__rmul__(2)`
>>> my_numbers.__rmul__(2)
[2, 4, 6, 2, 4, 6]
Let's look at
`2 * my_numbers`
The reflected multiplication special method `.__rmul__()` of the operand on the right (`my_numbers`) is called if the `.__mul__()` method of the left operand (`2`) returns `NotImplemented`
I've written more about this in the inaugural article on The Python Coding Stack in April
And there are more examples with `.__rmul__()` and `.__radd__()`, and more detailed explanation in the article
You can get to The Stack through my bio here…