Open In App

What is a clean and Pythonic way to have multiple constructors in Python?

Last Updated : 05 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Python does not support explicit multiple constructors, yet there are some ways to achieve multiple constructors.

We use Python’s inbuilt __init__ method to define the constructor of a class. It tells what will the constructor do if the class object is created.

If multiple __init__ methods are written for the same class, then the latest one overwrites all the previous constructors and the reason for this can be that Python stores all the function names in a class as keys in a dictionary so when a new function is defined with the same name, the key remains the same but the value gets overridden by the new function body.

PrerequisitesConstructors, @classmethod decorators

What happens when multiple __init__ methods are defined in a class

There can only be one __init__ method in a class.

If we create multiple __init__ methods, Python will only consider the latest __init__ method.

Note- A new __init__ method overwrites the previous __init__ method.

Example:

Python3




class example:
  
    def __init__(self):
        print("One")
  
    def __init__(self):
        print("Two")
  
    def __init__(self):
        print("Three")
  
  
e = example()


Output

Three

As you can see from the example above, if we try creating multiple __init__ methods, the latest __init__ method overwrites all previous __init__ methods.

Need for Multiple Constructors

Multiple constructors are required when one has to perform different actions on the instantiation of a Python class

This is useful when the class has to perform different actions on different parameters. 

How to Have Multiple Constructors in Python?

The class constructors can be made to exhibit polymorphism in three ways which are listed below.

  1. Overloading constructors based on arguments.
  2. Calling methods from __init__.
  3. Using @classmethod decorator.

Let’s see how to have multiple constructors in a clean and Pythonic way with examples.

Overloading constructors based on arguments

The constructor overloading is done by checking conditions for the arguments passed and performing the required actions. For example, consider passing an argument to the class sample

  • If the parameter is an int, the square of the number should be the answer.
  • If the parameter is a String, the answer should be “Hello!!”+string.
  • If the parameter is of length greater than 1, the sum of arguments should be stored as the answer.

Example:

Python3




class sample:
  
    # constructor overloading
    # based on args
    def __init__(self, *args):
  
        # if args are more than 1
        # sum of args
        if len(args) > 1:
            self.ans = 0
            for i in args:
                self.ans += i
  
        # if arg is an integer
        # square the arg
        elif isinstance(args[0], int):
            self.ans = args[0]*args[0]
  
        # if arg is string
        # Print with hello
        elif isinstance(args[0], str):
            self.ans = "Hello! "+args[0]+"."
  
  
s1 = sample(1, 2, 3, 4, 5)
print("Sum of list :", s1.ans)
  
s2 = sample(5)
print("Square of int :", s2.ans)
  
s3 = sample("GeeksforGeeks")
print("String :", s3.ans)


Output

Sum of list : 15
Square of int : 25
String : Hello! GeeksforGeeks.

In the code above, the instance variable was ans, but its values differ based on the arguments. 

Since a variable number of arguments for the class, *args is used which is a tuple that contains the arguments passed and can be accessed using an index. 

In the case of int and string, only one argument is passed and thus accessed as args[0] (the only element in the tuple).

Calling methods from __init__

A class can have one constructor __init__ which can perform any action when the instance of the class is created. 

This constructor can be made to different functions that carry out different actions based on the arguments passed. Now consider an example : 

  • If the number of arguments passed is 2, then evaluate the expression x = a2-b2
  • If the number of arguments passed is 3, then evaluate the expression y = a2+b2-c.
  • If more than 3 arguments have been passed, then sum up the squares, and divide it by the highest value in the arguments passed.

Example:

Python3




class eval_equations:
  
  # single constructor to call other methods
    def __init__(self, *inp):
  
        # when 2 arguments are passed
        if len(inp) == 2:
            self.ans = self.eq2(inp)
  
        # when 3 arguments are passed
        elif len(inp) == 3:
            self.ans = self.eq1(inp)
  
        # when more than 3 arguments are passed
        else:
            self.ans = self.eq3(inp)
  
    def eq1(self, args):
        x = (args[0]*args[0])+(args[1]*args[1])-args[2]
        return x
  
    def eq2(self, args):
        y = (args[0]*args[0])-(args[1]*args[1])
        return y
  
    def eq3(self, args):
        temp = 0
        for i in range(0, len(args)):
            temp += args[i]*args[i]
          
        temp = temp/max(args)
        z = temp
        return z
  
  
inp1 = eval_equations(1, 2)
inp2 = eval_equations(1, 2, 3)
inp3 = eval_equations(1, 2, 3, 4, 5)
  
print("equation 2 :", inp1.ans)
print("equation 1 :", inp2.ans)
print("equation 3 :", inp3.ans)


Output

equation 2 : -3
equation 1 : 2
equation 3 : 11.0

In the example above, the equation to be evaluated is written on different instance methods and made to return the answer. The constructor calls the appropriate method and acts differently for different parameters.

The expressions have been evaluated as follows:

inputs : 1,2 —> 12-22 = 1-4 = -3

inputs : 1,2,3  —> (12 + 22) – 3 = 5-3 = 2

inputs : 1,2,3,4,5 —> (12 + 22 + 32 + 42 + 52) / 5 = 55/5 = 11.0

Using @classmethod decorator

@classmethod decorator allows a function to be accessible without instantiating the class. The functions can be accessed both by the instance of the class and the class itself. 

The first parameter of the method that is declared as classmethod is cls, which is like the self of the instance methods. Here cls refer to the class itself. This proves to be very helpful in using multiple constructors in Python and is a more Pythonic approach compared to the above ones. 

Consider the same example used above. Evaluate different expressions based on the number of inputs.

Example:

Python3




class eval_equations:
  
    # basic constructor
    def __init__(self, a):
        self.ans = a
  
    # expression 1
    @classmethod
    def eq1(cls, args):
        
      # create an object for the class to return
        x = cls((args[0]*args[0])+(args[1]*args[1])-args[2])
        return x
  
    # expression 2
    @classmethod
    def eq2(cls, args):
        y = cls((args[0]*args[0])-(args[1]*args[1]))
        return y
  
    # expression 3
    @classmethod
    def eq3(cls, args):
        temp = 0
  
        # square of each element
        for i in range(0, len(args)):
            temp += args[i]*args[i]
  
        temp = temp/max(args)
        z = cls(temp)
        return z
  
  
li = [[1, 2], [1, 2, 3], [1, 2, 3, 4, 5]]
i = 0
  
# loop to get input three times
while i < 3:
  
    inp = li[i]
  
    # no.of.arguments = 2
    if len(inp) == 2:
        p = eval_equations.eq2(inp)
        print("equation 2 :", p.ans)
  
    # no.of.arguments = 3
    elif len(inp) == 3:
        p = eval_equations.eq1(inp)
        print("equation 1 :", p.ans)
  
    # More than three arguments
    else:
        p = eval_equations.eq3(inp)
        print("equation 3 :", p.ans)
  
    #increment loop        
    i += 1


Output

equation 2 : -3
equation 1 : 2
equation 3 : 11.0

In the example above, the instance of the object is not created initially. The class methods to evaluate various expressions have been defined with the @classmethod decorator. 

Now they can be called with the class name and the object is created in that class method after evaluating the expression. The instance variable holds different answers for a different number of parameters passed.

Conclusion

Creating a class with multiple constructors is a very useful aspect of OOP (object oriented programming). It allows user to simplify their code and gain more productivity.

Creating multiple constructors of a Python class is easier than you thought. We have covered three clean and Pythonic ways to have multiple constructors in a Python class. You can use any of the above methods, to create multiple constructors and gain multiple functionalities with its object.



Previous Article
Next Article

Similar Reads

Clean Web Scraping Data Using clean-text in Python
If you like to play with API's or like to scrape data from various websites, you must've come around random annoying text, numbers, keywords that come around with data. Sometimes it can be really complicating and frustrating to clean scraped data to obtain the actual data that we want. In this article, we are going to explore a python library calle
2 min read
Parse and Clean Log Files in Python
Log files are essential for comprehending how software systems behave and function. However, because log files are unstructured, parsing and cleaning them can be difficult. We will examine how to use Python to efficiently parse and clean log files in this lesson. In this article, we will see how to Parse and Clean log files in Python. Parse and Cle
3 min read
Best Practices to Write Clean Python Code
Python is one of the most loved programming languages today. Shockingly, Python has overtaken Java in the list of top programming languages and is now the most studied language! It is the second most used language after JavaScript and is slowly beating the competition to be on the top. It is used extensively across various domains like web developm
6 min read
Defining Clean Up Actions in Python
Think of a task you will always want your program to do, whether it runs perfectly or raise any kind of error. For example, We use of try statement which has an optional clause - "finally" to perform clean up actions, that must be executed under all conditions. Cleanup actions: Before leaving the try statement, "finally" clause is always executed,
3 min read
Clean the string data in the given Pandas Dataframe
In today's world data analytics is being used by all sorts of companies out there. While working with data, we can come across any sort of problem which requires an out-of-the-box approach for evaluation. Most of the Data in real life contains the name of entities or other nouns. It might be possible that the names are not in a proper format. In th
3 min read
Constructors in Python
Prerequisites: Object-Oriented Programming in Python, Object-Oriented Programming in Python | Set 2 Constructors are generally used for instantiating an object. The task of constructors is to initialize(assign values) to the data members of the class when an object of the class is created. In Python the __init__() method is called the constructor a
6 min read
Python Comments: Importance, Types and Correct Way to Use
Comments in Python are the lines in the code that are ignored by the interpreter during the execution of the program. # I am single line comment &quot;&quot;&quot; Multi-line comment used print(&quot;Python Comments&quot;) &quot;&quot;&quot; Comments enhance the readability of the code and help the programmers to understand the code very carefully.
4 min read
Python List Comprehension | Three way partitioning of an array around a given range
Given an array and a range [lowVal, highVal], partition the array around the range such that array is divided in three parts. 1) All elements smaller than lowVal come first. 2) All elements in range lowVal to highVal come next. 3) All elements greater than highVal appear in the end. The individual elements of three sets can appear in any order. Exa
3 min read
Change your way to put logic in your code - Python
Aren't you bored coding in the same traditional logic over these years. It's time to bring some differences. Well, be it any programming language. When we are asked to do some sort of basic programming exercises like sorting, searching, prime number checking, etc. we are all driven towards the same boat, which is the same coding logic. Now, we are
5 min read
Different way to create a thread in Python
A thread is an entity within a process that can be scheduled for execution. Also, it is the smallest unit of processing that can be performed in an Operating System. There are various ways to create a thread: 1) Create a Thread without using an Explicit function: By importing the module and creating the Thread class object separately we can easily
4 min read
three90RightbarBannerImg