Alternative Constructors in Python
Published: 2021-10-29 15:27:43

## Article Agenda
This post is dedicated towards understanding how we can create **alternative constructors** in Python. Also, we would be taking a look at a real developmental scenario where I felt comfortable using it. To cut this short, we would be covering:
- **[Constructors](#constructors)**
- **[Alternative Constructors](#alternative-constructors)**
- **[A Real Application Example](#a-real-application-example)**

## Introduction
Python OOPs has rocked the world with its **simple yet stunning** flow of programming. Almost all the programs and software written in Python follow the OOPs paradigm. The OOP in Python is so modernized and enhanced that huge amount of developers are making a shift towards this amazing Programming language.

In case you are wondering what an OOP is, I already have a **[Python OOP](https://dev.to/p0intman/a-primer-on-object-oriented-programming-with-python-231g)** post on this, which gives you a brief overview about it. You may want to give it a thorough read.

## Constructors
![constructors](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/foohjioacc2sj090jvw2.png)
Constructors by definition, is a **subroutine designed to create an object in a particular class**. In layman's terms, a _method_, which gets **automatically called at the time of object creation and assists it**.

Constructors are like ordinary methods defined inside the class. The only difference being, we need **not** call it explicitly. Programming languages automatically calls it while creating the object of the class.

In **C++**, constructors have the **same name** as the class name. For example (I know this is a Python tutorial, but I really felt the urge to show you the difference. So, here you go):
```c++
class MyClass          // Class name
{
public:
    int a, b;

    // Constructor. Notice how its name is same as class name
    MyClass()   
    {
        // I will be automatically executed during instantiation
    }
};
 
int main()
{
    MyClass obj;       // instantiation.
    
}
```

In Python, this is **not** the case. However, there is a _huge misconception_ out there:

### The `__init__()` vs `__new__()`. Which one is the real constructor?
As opposed to a popular yet **wrong** belief where **`__init__()` method is considered to be constructor, its actually the `__new__()` method which is the constructor of the class**. To put it more clearly:
- **`__new__()`** : This method is called automatically to **control** the object creation.
- **`__init__()`** : This method is also called automatically during object creation, but this is more of an **initializer method** which initializes the object attributes. That's why we used it in our OOPs concept (an earlier post), to initialize our object attributes.

Moreover, if both **`__new__()`** and **`__init__()`** methods exist in the same class, then **`__new__()`** is called first and then Python interpreter decides whether to call **`__init__()`** or not. 

So, from the OOP standpoint, and from the above observations, it can be safely concluded that **`__new__()`** is the **real constructor**. But several Devs just want to stay out of this pandemonium. Therefore, instead of going after this **_"init vs new thing"_**, they adopted another way to create constructors, enter the _Alternative Constructors_

## Alternative Constructors
![ac](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d4oebat8xj8gbtvoimvd.png)
Alternative constructors are actually **class methods** which serves the purpose of object creation. We hack the **class methods** and command them to control the object creation. This is pretty similar to a constructor's (`__new__()`'s) working. 

There is a convention for naming methods to be used as alternative constructors. All such methods should start with **`from_`**. For example, if I have a method say, **`getDetails()`** and if I were to make it an alternative constructor, then I would have to rename it as **`from_getDetails()`**. Although this is not necessary, but it is considered to be a good practice.

The following snippet shows the basic syntax of defining alternative constructors (AC):

```python
class MyClass:
    
    @classmethod
    def from_alternativeConstructor(cls):      # Alternative Constructor
        return cls()                           # returns object

object = MyClass.from_alternativeConstructor() # calling AC

# an object is crafted successfully due to the execution of AC
```

## A Real Application Example
![EXAMPLE](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/92dh8csug5o5sgg96e31.png)
While I was developing a backend, I had a long list of strings. I had to come up with a way to convert these **strings to objects**. Luckily, I had AC by my side and the task went on smoothly. In real world, you would get raw data like these. You would have to circumvent these obstacles and find a solution. 

The following snippet shows a demonstration of how I converted a long list of strings (but here, for the sake of simplicity, lets take a single string) and then converted it into objects.

```python
class Professor:
    
    def __init__(self,name,id,age):
        self.name = name
        self.id = id
        self.age = age

    @classmethod
    def from_getDetails(cls, string):      # Alternative Constructor
        name, id, age = string.split(',')  # split string and assign to variables
        return cls(name,id,age)            # returns object

details = "Jack Robins,2233394,45"

prof = Professor.from_getDetails(details)  
print(prof.name,prof.id,prof.age)          # prints --> "Jack Robins" 2233394 45
```
The string is now converted to an object and I can easily access it using its attributes. So, this was all about alternative constructors. One of the most interesting ways to bypass the basic working system of OOPs and also, exploiting the most out of it. After all, we are programmers, its in our DNA to exploit stuff and get things working for us.

## Would You Like to Support Me?
If you want to support me and my contents, then go ahead and consider doing it. I would highly appreciate that:

- [YouTube Channel](https://www.youtube.com/channel/UC1QZPervOHLiC4xpVnzbDFg): Home to all sorts of **peculiar** tutos.
- [GitHub](https://www.github.com/P0intMaN): Looking forward to your PR 😉