Define method aliases in Python?

14,635

Solution 1

self will never be the number in __mul__() because the object the method is attached to is not the number, it's the vector, and by definition it's the multiplicand.

other will be a number if your object is being multiplied by a number. Or it could be something else, such as another vector, which you could test for and handle.

When your object is the multiplier, __rmul__() is called if the multiplicand doesn't know how to handle the operation.

To handle the case in which __mul__ and __rmul__ should be the same method, because the operation is commutative, you can just do the assignment in your class definition.

class Vector(object):
    def __mul__(self, other):
        pass

    __rmul__ = __mul__

Solution 2

Simply list it as an attribute:

__rmul__ = __mul__

This is the same way you'd create an alias of a function in a module; creating an alias of a method within a class body works the same.

Solution 3

The point is that in Python, you can tell objects how to multiply themselves by things. That means that

a * b

could either mean "tell a to multiply itself by b" or "tell b to multiply itself by a". In code, that translates to

a.__mul__(b)

or

b.__rmul__(a)
Share:
14,635
Zoé Martin
Author by

Zoé Martin

Updated on June 01, 2022

Comments

  • Zoé Martin
    Zoé Martin almost 2 years

    I have a vector class and I defined the __mul__ method to multiply a vector by a number.

    Here is the __mul__ method :

    def __mul__(self, other):
        x = self.x * other
        y = self.y * other
        new = Vector()
        new.set_pos((x, y))
        return new
    

    My problem is that I don't know which is which between the number and the vector. If self is the number, self.x raises an error. (I'm maybe mistaking on this point : Is "other" always a number ?)

    So I found here : Python: multiplication override that I could do :

    __rmul__ = __mul__
    

    but how can I do that in a class definition ?

    Something like :

    def __rmul__ = __mul__
    
  • Jeremy Pridemore
    Jeremy Pridemore almost 12 years
    Is there a way to know which one will be called?
  • Katriel
    Katriel almost 12 years
    __mul__ first, then __rmul__ if that fails.
  • glglgl
    glglgl almost 12 years
    better: or "tell b to multiply a by itself (b)". The multiplication operator doesn't have to be commutative.
  • gansub
    gansub about 2 years
    Am I right in concluding that you are doing the assignment in the init method ?
  • kindall
    kindall about 2 years
    no, it's in the class definition.
  • gansub
    gansub about 2 years
    Ok thanks I googled for an example of this but could not find one. Final question. By putting it in the class definition the method alias assignment has global scope ?
  • kindall
    kindall about 2 years
    global as in all instances of that class will have that behavior, yes.