[Tutor] Method overloading in Python

Mats Wichmann mats at wichmann.us
Thu Nov 4 12:04:21 EDT 2021


On 11/4/21 06:39, Manprit Singh wrote:
> Dear sir,
> 
> Although Method overloading  can't be truly achieved in Python , But a
> similar effect can be made to happen - like if a method or __init__ () can
> behave differently in case of different types of inputs.
> I have written an example below to show it :
> 
> In this example i have  made a class Awards, My purpose of this class is to
> get the name of award based on category
> for category "A" or 1 award is "TV"
> for category "B" or 2 award is "AC"
> for category "C" or 3 award is "Fridge"
> 
> The program allows user to  give input of category either in string from or
> in integer from, means the program must give result   as "TV" when the
> category is either A or 1
> 
> class Awards:
>      cat1 = {"A": "TV", "B": "AC", "C": "Fridge"}
>      cat2 = {1: "TV", 2: "AC", 3: "Fridge"}
> 
>      def __init__(self, cat=None):
>          if isinstance(cat, str):
>              self.award = self.cat1[cat]
>          elif isinstance(cat, int):
>              self.award = self.cat2[cat]

Notice you have a default of None, meaning you're allowing the user to 
call with no arguments also, but you have no case for that.  On the 
other hand, this can have some advantages too, see below.

> 
>      def showaward(self):
>          return self.award
> 
> prize = Awards(1)
> print(prize.showaward())    # prints "TV  which is right answer for
> category 1
> 
> prize = Awards("A")           # prints "TV  which is right answer for
> category "A
> print(prize.showaward())
> 
> Here I have overloaded the __init__() , as it is behaving differently in
> case of integer input and differently in case of string input. It will
> assign "TV" to self.award if the  object creation is done either  with 1 or
> "A" as argument  passed during class instantiation.  Is my thinking correct
> ?

There are a couple of ways to achieve this "overloading".  One is how 
you've done it, which is to have the initializer handle different ways 
of calling.

Another way is to write a factory function that fronts the class 
definition, fiddling the arguments into some kind of common style, or 
passing some additional data like the already looked up data from the 
catalogs, and then your init method just becomes something like:

def __init__(self, award):
     self.award = award


  A another way is to provide an alternate initializer something like this:

     @classmethod
     def from_int(cls, cat):
         """ alternate initializer that takes an int argument """
         self = cls()
         self.award = self.cat2[cat]

That has the disadvantage that the "overloading" is user-visible, Which 
is also an advantage - depending on whether you think explicit is good 
or bad here.

Yet another approach is to use the functools module, which has 
singledispatch and singledispatchmethod calls - singldispatchmethod 
would be the one for this case.  I guess some people would consider that 
"advanced" Python so I won't go further into it here, but feel free to 
read up on it.

> My second question is if a class can have more than one class variable,
> here I have put 2 class variables in the class cat1 and cat2 . Kindly
> comment .

There''s no limit on number of class vaiables.


More information about the Tutor mailing list