Python Intermediate: How to use Constructors in Python

Constructors in Python

Constructors are often used to create an object. Constructors are responsible for initializing (assigning values) the class’s data members when an object of the class is created. The __init__() function is known as the constructor in Python and is always called when an object is created.

The Syntax of Constructors:

def __init__(self):
    # body of the constructor

There are two kinds of constructors:

The default constructor is a straightforward constructor that does not accept any parameters. Its definition only takes one argument, which is a reference to the instance being built.

Another one is a parameterized constructor, which is a constructor that accepts parameters. The parameterized constructor accepts a reference to the instance being formed known as self as its first argument, and the rest of the parameters are given by the programmer.

Default constructor

This is the default constructor, which is a simple constructor that does not accept any parameters. Its definition only takes one argument, which is a reference to the instance being constructed.

Example:

class Book:
 
   def __init__(self):
       self.name = "The Alchemist"
 
   def print_name(self):
       print(self.name)
 
obj = Book()
obj.print_name()

Output:

The Alchemist

Parameterized constructor

When we don’t want to manipulate the value, we use the non-parameterized constructor. Take the example that follows.

Example:

class Multiplication:
   first = 1
   second = 1
   answer = 0
  
   def __init__(self, x, y):
       self.first = x
       self.second = y
  
   def print_answer(self):
       print("Number1 = " + str(self.first))
       print("Number2 = " + str(self.second))
       print("Multiplication of two numbers = " + str(self.answer))
 
   def calculate(self):
       self.answer = self.first * self.second
 
My_object = Multiplication(38, 34)
 
My_object.calculate()
 
My_object.print_answer()

Output:

Number1 = 38
Number2 = 34
Multiplication of two numbers = 1292

Making Custom Object Initializers Accessible

The most basic implementation of .__init__() will simply assign input arguments to match instance attributes. Assume you’re creating a Rectangle class that requires. width and. height attributes. In that case, you can do the following:

Example:

class Binary:
   def __init__(self, f, s):
       self.first = f
       self.second = s
 
two_bytes = Binary(10001011, 11011001)
 
first_byte = two_bytes.first
second_byte = two_bytes.second
 
print(first_byte, second_byte)

Output:

10001011 11011001

It’s worth noting that, excluding self, the arguments to .__init__() are the same ones you passed to the class constructor. In a sense, the .__init__() signature defines the signature of the class constructor.

The construction of flexible object initializers

By modifying the .__init__() method, you can make the initialization of your objects more flexible and versatile. One of the most popular approaches is to use optional arguments. This technique enables you to create classes with constructors that accept different sets of input arguments at instantiation time. Which arguments to use at any given time will be determined by your specific requirements and context.

Consider the following evaluation class as an example:

Example:

class Evaluation:
   def __init__(self, statement, formal=False):
       self.say = statement
       self.formal = formal
 
   def announce(self):
       if self.formal:
           print(f"Great performance, You have got {self.say} marks.")
       else:
           print(f"Good, You have got {self.say} marks.")
          
normal = Evaluation(75)
normal.announce()
 
 
formal = Evaluation(95, formal=True)
formal.announce()

Output:

Good, You have got 75 marks.
Great performance, You have got 95 marks.

Object Creation With .__new__()

You usually don’t need to provide your own implementation of the .__new__() special method when writing Python classes. The base implementation from the built-in object class is usually sufficient to create an empty object of your current class. However, this method has a few intriguing applications. You can, for example, use .__new__() to create subclasses of immutable types like int, float, tuple, and str.

You’ll learn how to write custom implementations of .__new__() in your classes in the sections that follow. To accomplish this, you’ll write a few examples that will show you when you might need to override this method.

Example:

# Run this many times and see the output
from random import choice
 
class Languages:
   def __new__(cls):
       other = choice([Java, Go, Python])
       instance = super().__new__(other)
       print(f"This is {type(instance).__name__}!")
       return instance
 
   def __init__(self):
       print("Don't afraid")
 
class Java:
   def logo_description(self):
       print("Blue coffee cup with red steam above it")
 
class Go:
   def logo_description(self):
       print("Go gopher is a character; just as Snoopy and Rat.")
 
class Python:
   def logo_description(self):
       print("The emblem depicts a two-colored snakes image")
      
lang = Languages()
lang.logo_description()
isinstance(lang, Languages)
isinstance(lang, Java)
mylang = Languages()
mylang.logo_description()

Output 1:

This is Java!
Blue coffee cup with red steam above it
This is Java!
Blue coffee cup with red steam above it

Output 2: Run the previous code once again.

This is Python!
The emblem depicts a two-colored snakes image
This is Python!
The emblem depicts a two-colored snakes image

You now understand how Python class constructors enable you to instantiate classes and create concrete, ready-to-use objects in your code. Class constructors in Python initiate the instantiation or construction process, which includes instance creation and instance initialization. The .__new__() and .__init__() special methods drive these steps. You can now control how your custom classes construct new instances by learning about Python’s class constructors, the instantiation process, and the .__new__() and .__init__() methods. In this tutorial, you learned how Python’s instantiation process works internally. How to use your own .__init__() methods to customize object initialization. Overriding the .__new__() method allows for the creation of custom objects. Now you’re ready to use this knowledge to fine-tune your class constructors and gain complete control over instance creation and initialization in your Python object-oriented programming adventure.

Share The Tutorial With Your Friends
Twiter
Facebook
LinkedIn
Email
WhatsApp
Skype
Reddit

Check Our Ebook for This Online Course

Advanced topics are covered in this ebook with many practical examples.