Parth Patel
Parth Patel

Reputation: 148

Method Overloading is not working when arguments are different

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?

Upvotes: 0

Views: 416

Answers (1)

chepner
chepner

Reputation: 532518

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)

Upvotes: 2

Related Questions