Python Object-Oriented-Programming

In this tutorial, you will learn about Object-Oriented Programming (OOP) in Python and its fundamental concept with the help of examples.

Python Classes and Objects

Think of a class as a blueprint of a house. It contains all the details about the floors, doors, windows, etc.

Based on these descriptions, we build the house. The actual physical house is the object.

Object oriented programming: Classes and Objects
Blueprint (class) and houses (objects)
class Student:
    pass

student1 = Student()
student2 = Student()

Here, student1 and student2 are objects of the Student class.

Now, we can start adding different attributes to these object instances.

class Student:
    pass

# create an object of Student
student1 = Student()

# initialize object attributes
student1.name = 'Harry'
student1.marks = 85

# print object attributes
print(student1.name)
print(student1.marks)

Output

Harry
85

Let's now see how we can define methods inside a class.

class Student:

    # method to check if student passed or failed
    def check_pass_fail(self):
        if self.marks >= 40:
            return True
        else:
            return False

# instantiate Student class
student1 = Student()

# initialize data attributes of student1
student1.name = 'Harry'
student1.marks = 85

# call the check_pass_fail() method for student1
did_pass = student1.check_pass_fail()

# print the result
print(did_pass)

Output

True

Here, the check_pass_fail() method is defined inside the Student class. Now, any object created from the Student class can access this method.

We have called this method without passing any arguments. However, the method definition takes one argument named self.

def check_pass_fail(self):
    if self.marks >= 40:
        return True
    else:
        return False

Whenever we define methods for a class, we need to use self as the first parameter. This self represents the object calling it.

In our example, self refers to the student1 object and self.marks refers to the marks attribute of student1.

Let's try the same for another Student object.

class Student:
    def check_pass_fail(self):
        if self.marks >= 40:
            return True
        else:
            return False

student1 = Student()
student1.name = 'Harry'
student1.marks = 85

did_pass = student1.check_pass_fail()
print(did_pass)

student2 = Student()
student2.name = 'Janet'
student2.marks = 30
did_pass = student2.check_pass_fail()
print(did_pass)

Output

True
False
student1 and student2 are objects of Student class
Student class and its objects

Note: Using self is just a convention, but we highly recommend using it.


The __init__() Method

Adding attributes to the object manually after defining it is not a good practice.

Python offers a much more elegant and compact way of defining attributes right while instantiating the object. For that, we use the init method.

If you are coming from other languages like C++ or Java, the Python __init__() method closely resembles constructors.

class Student:
    
    def __init__(self, name, marks):
        self.name = name
        self.marks = marks
        
    def check_pass_fail(self):
        if self.marks >= 40:
            return True
        else:
            return False

student1 = Student('Harry', 85)
print(student1.name)
print(student1.marks)

Output

Harry
85

When we create an object, this __init__() method is called automatically. When creating the student1 object, we have passed Harry and 85 to its name and marks attributes in the __init()__ method.

init parameters
Use of the init function

Remember, the first parameter self represents the object calling it. In contrast, the second and third parameters take the two arguments which we passed during object creation.

Now, for the student1 object, the name attribute will be Harry, and the marks attribute will be 85.

Let's try creating one more object.

class Student:
    
    def __init__(self, name, marks):
        self.name = name
        self.marks = marks
        
    def check_pass_fail(self):
        if self.marks >= 40:
            return True
        else:
            return False

student1 = Student('Harry', 85)
print(student1.name)
print(student1.marks)

student2 = Student('Janet', 30)
print(student2.name)
print(student2.marks)

Output

Harry
85
Janet
30

The table below shows the attributes of student1 and student2.

Object name marks
student1 Harry 85
student2 Janet 30

Let's check if they passed or failed the exams using the check_pass_fail() method.

class Student:
    
    def __init__(self, name, marks):
        self.name = name
        self.marks = marks
        
    def check_pass_fail(self):
        if self.marks >= 40:
            return True
        else:
            return False

student1 = Student('Harry', 85)
did_pass = student1.check_pass_fail()
print(did_pass)

student2 = Student('Janet', 30)
did_pass = student2.check_pass_fail()
print(did_pass)

Output

True
False
Object marks marks >= 40
student1 85 True
student2 30 False

Example: Add Two Complex Numbers

In this example, we will add two complex numbers manually. Python already handles this by default, but we will create our own Complex class to better understand the concepts of object-oriented programming.

If you do not know, a complex number has real and imaginary parts. When we add two complex numbers, we need to add real and imaginary parts separately.

Let's first create a class that represents complex numbers.

class Complex:
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag

n1 = Complex(5, 6)
n2 = Complex(-4, 2)

Now, let's create a method to add these complex numbers.

class Complex:
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag
        
    def add(self, number):
        real = self.real + number.real
        imag = self.imag + number.imag
        sum = Complex(real, imag)
        return sum

n1 = Complex(5, 6)
n2 = Complex(-4, 2)
result = n1.add(n2)

The value returned by add() is itself an object of the Complex class.

Let's print the attributes of the result object.

class Complex:
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag
        
    def add(self, number):
        real = self.real + number.real
        imag = self.imag + number.imag
        sum = Complex(real, imag)
        return sum

n1 = Complex(5, 6)
n2 = Complex(-4, 2)
result = n1.add(n2)

print('real =', result.real)
print('imag =', result.imag)

Output

real = 1
imag = 8

Here, the n1 object is calling the add() method by passing n2 as an argument. The return value of the complex addition is then stored in the result object.


Why object-oriented programming?

Creating objects allows us to organize related data and functionalities together. This helps us to write structured and flexible code.

Now, instead of thinking in terms of individual data and functions, we start thinking in terms of objects and how one object interacts with the other. This helps us to divide a complex problem into smaller sub-problems.

Also, using an object-oriented style of programming makes our code reusable because we can define multiple objects with similar attributes and functionalities from a single class.


Programming Task

  1. Create a class named Triangle.
  2. Create an object from it. The object will have three attributes named a, b, and c that represent the sides of the triangle.
  3. The Triangle class will have two methods:
    1. The __init__() method to initialize the sides.
    2. A method to calculate the perimeter of the triangle from its sides.
  4. The perimeter of the triangle should be printed from outside the class.

Here's the barebone for this program:

cclass Triangle:
    def __init__(self, a, b, c):
        # write code here
        pass
    
    # write code here
    
t1 = Triangle(3, 4, 5)
# write code here

Solution

class Triangle:
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c
    
    def get_perimeter(self):
        perimeter = self.a + self.b + self.c
        return perimeter
    
t1 = Triangle(3, 4, 5)

perimeter = t1.get_perimeter()
print('The perimeter of the t1 triangle is', perimeter)

Output

The perimeter of the t1 triangle is 12
Did you find this article helpful?