pythonoverridingoperator-keyword

Python: multiplication override


So, I've got a custom class that has a __mul__ function which works with ints. However, in my program (in libraries), it's getting called the other way around, i.e., 2 * x where x is of my class. Is there a way I can have it use my __mul__ function for this?


Solution

  • The simplest way is to add the following to the class definition:

    __rmul__ = __mul__
    

    In general (as explained in CatPlusPlus's answer, an __rmul__ override is needed to solve the problem. This is one of the "reverse" operator magic methods that Python uses to implement binary operators. In the example in the question, since int.__mul__ doesn't handle the custom type, the custom type will be checked for a .__rmul__ which can handle an int operand.

    The alias shown above will reuse the custom type's existing __mul__ implementation for __rmul__. This entails that 2 * x will have the same result as x * 2. This is not necessarily correct for all use cases. In general, you must think carefully about the intended semantics of multiplication, because multiplication is not always commutative.

    For example, suppose you have vector and matrix classes, and you want to define multiplication between them, within the matrix class. For __mul__ you can treat the vector as if it were a 1xN matrix. However, to correctly multiply a vector by a matrix, you'd need to treat the vector as a Nx1 matrix, and keep it on the left-hand side. Making this work cleanly (without duplicating code) might involve delegating both __mul__ and __rmul__ to a common implementation, creating a temporary matrix instance from the vector, etc.