0

I am working on a small project where I have to use method overloading for mul method. But that mul method has a different arguments.

Method can take 2 argument 1st is self and 2nd is either Instance or integer. So when Method take 2nd argument as Instance it gives me an error. Here is my code

import math
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __mul__(self,v1):
        x = self.x * v1.x
        y = self.y * v1.y
        return Vector(x,y)

    def __mul__(self,n):
        x = self.x*n
        y = self.y*n 
        return Vector(x,y)


v1 = getVector()
v2 = getVector()
v3 = v1 * v2 

v4 = 1
v5 = getVector()
v6 = v4 * v5

So when I am trying to run the program I am getting error that

File "Al.py", line 102, in <module>
    main()
  File "Al.py", line 88, in main
    mul()
  File "Al.py", line 47, in mul
    v3 = v1 * v2
  File "Al.py", line 21, in __mul__
    x = self.x*n

Can someone help me to understand this? How can I call the overloaded method without making any changes to my method signature?

5
  • 5
    Python doesn't support overloading. Instead write one method in which you check parameter type and process parameter accordingly. Commented Dec 2, 2017 at 1:15
  • Which Python version do you use? Remove the wrong tag. Commented Dec 2, 2017 at 1:17
  • 1
    It does not related to version. Commented Dec 2, 2017 at 1:18
  • 1
    Python can have only one function by a given name in a given namespace. By redefining __mul__, you wiped out the first version. Commented Dec 2, 2017 at 1:19
  • Unlike, say, C++, Python does not consider the number of arguments nor their type to be part of a method's signature, only it's name. To fake overloading, the __mul__() method would need to explicitly check the number and type of arguments it was passed to determine what to do. Commented Dec 2, 2017 at 1:59

1 Answer 1

2

As mentioned in the comments, Python does not support method overloading. Instead, you have to examine the argument(s) in the body of the function to determine how to proceed.

Note that you generally do not examine the type of the argument(s), but rather their behavior. For example,

def __mul__(self, other):
    try:
        try:
            x = self.x * other.x
            y = self.y * other.y
        except AttributeError:
            x = self.x * other
            y = self.y * other
    except Exception:
        return NotImplemented

    return Vector(x, y)

__rmul__ = __mul__   # Allows 4 * v, not just v * 4

The second argument of __mul__ doesn't have to be just an number or a Vector; it can be anything that is similar enough to either for the attempted multiplications to succeed.

On any other error involving the multiplication, return NotImplemented so that type(other).__rmul__ can be tried.

If you really need to differentiate between arguments of different types, use isinstance:

def __mul__(self, other):
    if isinstance(other, int):
        x = self.x * other
        y = self.y * other
    elif isinstance(other, Vector):
        x = self.x * other.x
        y = self.y * other.y
    else:
        return NotImplemented

    return Vector(x, y)
Sign up to request clarification or add additional context in comments.

2 Comments

In the first sentence, do you mean method overloading/overloading in general, rather than operator overloading? I have seen operator overloading refer to simply custom dunder methods such as __mul__
Good clear explanation. Might be worth noting that isinstance() can check multiple candidate types in one call by passing a tuple of them as the second argument: i.e. isinstance(other, (int, float)).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.