[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