Introduction to Object Oriented Programming in Python

The software industry is growing day by day. Many people leave an organization, and many new join the team, which leads to code changing hands frequently. So writing well-designed modular, reusable and extensible code is necessary. To achieve this objective, we use the concept of object-oriented programming.

In this blog, we will explain fundamental oops concepts in Python.

  • What are classes and objects in Python?
  • How to use Python classes and objects?
  • Default classes examples in Python
  • Abstraction, Inheritance and Polymorphism

What is a Class?

Class and Object relationship example

A class is a blueprint of an object, where we define attributes and methods working on those attributes. For a given class, we can create multiple objects.

For example, we can define several different objects of an Animal class like a Dog, Deer, Lion, etc., which are created based on the various attributes and methods described in the class Animal. We can define attributes such as their sound, height, and type of animal like herbivore, carnivore, omnivore, etc.

The attributes can be said to be of the following types:

  • Class variable: It is a variable shared by all different objects and classes of a variable
  • Instance variable: A variable defined in each instance using a method.

Many of us might be wondering what methods are. Methods are the name of functions defined under a class in Python. Let us look into the syntax of a class in Python.

class class_name:
    Statement_1
    Statement_2
    .
    .
    Statement_n

We create a class in Python using a class followed by the name of the class we want, followed by a colon name. An example is shown below.

class employee_details:
    pass
emp1 = employee_details()
emp1.first_name = "Harshit Agarwal"
emp1.experience = "3.5 years"
print(emp1.first_name)

###output
Harshit Agarwal

Here we have defined no attributes or methods for the class. We do not want to set the values manually. So let us look in the next section at how to use the __init__ function for the same.

Methods and Attributes

We create a class as discussed before. Now the created class should have some functions or methods to perform well, which helps us better use classes. Normally __init__ method is used in Python, which gets called whenever a new object is instantiated. We can also call these constructors for other languages, such as C++ and Java.

class employee_details:

    def __init__(self,name,salary,experience):
        self.name  = name
        self.salary = salary
        self.experience = experience

emp1 = employee_details("Harshit Agarwal",100000,"3.5 years")
print(emp1.experience)

Now inside __init__ method we have (self, name, salary, experience). Here self refers to the instance of class, i.e., employee_details in this case. We pass the required values to this init function, and as seen inside this function, values are assigned, thus becoming an automatic process for us in the future. Let us add one more method here, which shows us the name and salary in a single line.

class employee_details:
    def __init__(self,name,salary,experience):
        self.name  = name
        self.salary = salary
        self.experience = experience
        
    def name_salary(self):
        return self.name + "has a salry of -- " + str(self.salary)
        
emp1 = employee_details("Harshit Agarwal",100000,"3.5 years")
print(emp1.name_salary())

###output
Harshit Agarwalhas a salry of -- 100000

Method name_salary was created so that a method can access name and salary together. We use ‘self’ here to use this method with every object in Python.

In the below example, we use a class variable which is percentage_inc. This variable helps us increase a person’s salary using a new method. Please note that the class variables remain the same for all Python objects created from the same class. These variables are defined outside init and other methods. It is accessed using self-in methods.

class employee_details:
    percentage_inc = 1.1
    def __init__(self,name,salary,experience):
        self.name  = name
        self.salary = salary
        self.experience = experience
    
    def name_salary(self):
        return self.name + "has a salry of -- " + str(self.salary)
      
    def new_salary(self):
        self.salary = self.salary * self.percentage_inc

emp1 = employee_details("Harshit Agarwal",100000,"3.5 years")
print(emp1.name_salary())
emp1.new_salary()
print(emp1.salary)

Let us understand attributes in Python.

Attributes in Python

Attributes define the property of an object in Python. We can use the dir function to get a list of Python’s available attributes and methods.

dir(employee_details)
###output
['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'name_salary',
 'new_salary',
 'percentage_inc']

Above all, those with an underscore are default methods and attributes in Python. Others are user-defined methods and attributes.

Built-in-attributes: As shown in the example above, the underscore is already predefined attributes and functions provided by Python. For example, __dict__ returns all key-value pairs of an object as a dictionary. It is a predefined attribute of Python. We use it with object emp1 below.

emp1.__dict__
###output
{'name': 'Harshit Agarwal',
 'salary': 110000.00000000001,
 'experience': '3.5 years'}

User-Defined Attributes: These attributes are defined by users that we can apply to actions, data type definitions, and variables.

We have been using objects a lot. So let us look into this in the next section.

Objects in OOPS

Objects are used to access attributes of a class. Instances are objects created at run time. We also saw an example above where Animals were the class and the dog was the object. In the above criteria, emp1 was an object we created at runtime. As shown below, multiple objects can be made from the same class with different attributes.

emp1 = employee_details("Harshit Agarwal",100000,"3.5 years")
emp2 = employee_details("Raj Kumar",200000,"5.5 years")

emp2 is another object created here with different parameters passed for the __init__ method of the class. In the next section, let us look into some default examples of classes in Python.

Default classes examples in Python

We have some of the following types in Python:

  • list : [1,2,3]
  • int: 1, 2 ,3
  • float: 1.1 , 1.4, 1.5
  • dict: {1:2 , 3:4}
  • String: “hello”, “help”, “hello world”

Each data type can be said, class. When we define a class type, like for int the numbers 1, 2, 3, then we create three objects or instances of type int here. We also use methods of these classes; a very classic example is the list. Sort() and reverse() are two methods of the list. These built-in functions provided by the Python package are beneficial for us.

l =[1,3,5,9,0]
l.sort()
print(l)
l.reverse()
print(l)

###output
[0, 1, 3, 5, 9]
[9, 5, 3, 1, 0]

The sort method is used to sort the list. The ‘reverse’ method is used to reverse the list, i.e., the first index becomes the last and vice versa.

We have seen till now how to use classes and objects in Python. The objects in Python work like mini program modules where each module is used to store different information whose structure is based on the original class. This helps us to maintain a better system of code and organize it. We can use these in several ways, especially how different classes are linked. Let us understand Inheritance in the next section.

Inheritance

Inheritance allows us to inherit the attributes and methods of the parent class. Here we have a concept of child class and parent class. Child class refers to the class that inherits attributes, while the parent class refers to the class whose methods and attributes are inherited. Based on the relation between child class and Parent class, Inheritance is divided into four categories: single, multilevel, hierarchical, and multiple inheritances, as shown in the figure below. We also have the benefit that child classes can supersede parent class methods, just like defining a custom function for each object. For more details, please refer to our blog.

Single, Multiple, Hierarchial, Multiple Inheritance methods

We see the code in Python where we define a child class by the name of ‘MLengineer’. When we define child class, all methods are inherited by the child class. Also, the class variable ‘percentageinc’ value is specifically different for the child class, showing supersede for Parent class.

class employee_details:
    percentage_inc = 1.1
    def __init__(self,name,salary,experience):
        self.name  = name
        self.salary = salary
        self.experience = experience
        
    def name_salary(self):
        return self.name + "has a salry of -- " + str(self.salary)
      
    def new_salary(self):
        self.salary = self.salary * self.percentage_inc

class ML_engineer(employee_details):
    percentage_inc = 3.0
    
emp1 = employee_details("Harshit Agarwal",100000,"3.5 years")
emp1.new_salary()
print("Parent class salary with increase in 1.1 --" , emp1.salary)

child1 = ML_engineer("Harshit Agarwal",100000,"3.5 years")
child1.new_salary()
print("child class salary ie 3 times --:", child1.salary)

###output
Parent class salary with increase in 1.1 -- 110000.00000000001
child class salary ie 3 times --: 300000.0

The above output tells us that for the same data fed to parent class and child class, the increase in salary based on the ‘new_salary’ function is three times. This is the concept of Inheritance. Defining inherited classes helps us to reduce the code and reuse it. Let us look into Polymorphism in the next section.

Polymorphism

Polymorphism ensures that the child class does not need to inherit all the methods. Some methods can supersede the child class. Polymorphism in OOPs refers to the ability of an object to behave differently according to the context of invocation. For more details, please refer to our blog.

class employee_details:
    percentage_inc = 1.1
    def __init__(self,name,salary,experience):
        self.name  = name
        self.salary = salary
        self.experience = experience
    
    def name_salary(self):
        return self.name + " has a salry of -- " + str(self.salary)
    
    def new_salary(self):
        self.salary = self.salary * self.percentage_inc

class ML_engineer(employee_details):
    def name_salary(self):
        return self.name[:5] + " has a salry of -- " + str(self.salary * 99)

emp1 = employee_details("Harshit Agarwal",100000,"3.5 years")
print(emp1.name_salary())

child1 = ML_engineer("Harshit Agarwal",100000,"3.5 years")
print(child1.name_salary())

###output
Harshit Agarwal has a salry of -- 100000
Harsh has a salry of -- 9900000

We define a child class with the name ‘MLengineer’. An object is created with the word ‘child1’. The method ‘namesalary’ is changed for child class. We see the difference in output which is an increase in salary multiplied by 99, and only the first five letters of the name are taken. We learn about Abstraction in the next section.

Abstraction

Abstraction allows us to program an interface and hide the implementation details. A typical example can be a car where we know that Ferrari, Bullero, and Bumblebee are all cars, but we have no idea about the internal parts of cars or their workings.

We use @abstractmethod on class methods to make it an Abstract Class.

# Python program showing
# abstract base class work
from abc import ABC, abstractmethod
class Animals(ABC):
    
    @abstractmethod
    def voice(self):
        pass
class Cat(Animals):
    def voice(self):
        print("meow")

A = Cat()
A.voice()

###output
meow

Conclusion

We have covered essential concepts of classes and objects and understood how to implement them in Python. Overall, class and objects are very instrumental in depicting real-life scenarios. They are used for implementing various OOPS concepts and making our life easier.

Enjoy learning!

Share feedback with us

More blogs to explore

Our weekly newsletter

Subscribe to get weekly content on data structure and algorithms, machine learning, system design and oops.

© 2022 Code Algorithms Pvt. Ltd.

All rights reserved.