Skip to content

OOP vs Procedural Programming in Python: A Comprehensive How-To Guide

Updated: at 04:56 AM

Object-oriented programming (OOP) and procedural programming are two fundamental programming paradigms. They each take a different approach to organizing code and handling data. This comprehensive guide examines the key differences between object-oriented and procedural programming in Python, including code examples and an analysis of the advantages of each approach.


Python supports both object-oriented and procedural programming methods. Understanding the differences between the two paradigms is critical for new programmers looking to master the Python language.

This guide will cover:

Table of Contents

Open Table of Contents

Defining OOP and Procedural Programming

Let’s start with a high-level definition of each programming paradigm:

Object-oriented programming (OOP) organizes code into objects that combine data and behaviors. Objects can represent real-world entities like customers, orders, etc. OOP aims to increase code reusability and flexibility by modeling hierarchical relationships.

Procedural programming structures code into procedures or functions that operate on data. The procedures divide tasks logically rather than splitting real-world elements into computerized objects.

Below we’ll explore these definitions in more detail, outlining the critical differentiators between the two approaches.

Key Differences Between OOP and Procedural Programming

While OOP and procedural programming are both valid approaches, they differ significantly in their structure and handling of data. Let’s examine some of the major differences:

Data Handling

In procedural programming, data moves freely around the system. Any procedure can access and modify any data structure.

In OOP, objects encapsulate the data they need to function. An object’s internal data can only be accessed or modified through its defined methods. Other objects don’t have direct access to its data.

# Procedural
name = "John"

def print_name():

# Object-oriented
class Person:
  def __init__(self, name): = name

  def print_name(self):

person = Person("John")
person.print_name() # Prints "John"

The procedural approach relies on free-floating, global data while OOP data lives within an object instance.


Procedurally structured programs break tasks into functional units called procedures or modules. These focus on steps or algorithms.

OOP programs break real-world entities into software objects with encapsulated data and behaviors. The architecture focuses on modeling objects and hierarchies.

# Procedural

def print_report(report_data):
  # Algorithm for formatting and printing report

# Object-oriented

class Report:
  def __init__(self, data): = data

  def print(self):
    # Formatting and printing logic

report = Report(report_data)

Procedural code follows linear steps while OOP mimics interconnecting objects.

Reusability and Maintainability

Procedural code often contains duplicate elements that are hard to maintain. Functions must be rewritten or copied each time they’re needed.

OOP promotes reusability through inheritance. New classes can leverage logic from parent classes instead of rewriting methods. This makes code more maintainable.

# Procedural

def user_print(user):

def admin_print(admin):
  print(admin["name"] + " (Admin)")

# Object-oriented

class User:
  def __init__(self, name): = name

  def print(self):

class Admin(User):
  def print(self):
    print(f"{} (Admin)")

user = User("John")
user.print() # Prints "John"

admin = Admin("Jane")
admin.print() # Prints "Jane (Admin)"

The OOP version extends while procedural needs separate functions.

These examples demonstrate the core differences that dictate when OOP or procedural programming is better suited for a task. Next, we’ll explore OOP techniques and principles in more depth.

OOP Principles and Techniques in Python

Object-oriented programming entails several key concepts:

Classes and Objects

For example, a Person class could define name and age properties along with walk() and talk() methods. An object like john would be created from that class template.


This principle states that objects should encapsulate their internal data and methods. Other objects don’t have direct access. Interaction occurs through the object’s public API.

In Python, prefixing an identifier with _ denotes it as protected. Prefixing with __ denotes a private element.


Inheritance allows new classes to derive properties and methods from a parent class. This promotes code reuse.

For example, a Student class could inherit from a Person class and gain access to the properties and methods defined on Person.

class Person:
  def __init__(self, name, age): = name
    self.age = age

  def print_info(self):
    print(, self.age)

class Student(Person):

student = Student("Jane", 20)
student.print_info() # Inherited method

We can override inherited methods as needed.


This allows a common interface for different object types. For example, multiple classes could define a print() method customized for each class but with the same call interface.

Pros and Cons of OOP vs Procedural Programming

Let’s summarize the relative advantages and disadvantages of each approach:

OOP Pros:

OOP Cons:

Procedural Pros:

Procedural Cons:

Neither approach is objectively better in all cases. The strengths and weaknesses should guide the choice between paradigms.

When to Use OOP vs Procedural Programming

Based on the tradeoffs, here are some general guidelines on when to use each approach:

Use OOP When:

Use Procedural When:

For complex projects, OOP is typically preferable. But procedural programming still has its niche uses cases and advantages.

Now let’s look at some example code contrasting the two paradigms.

OOP vs Procedural Programming Example

To see the differences in action, we’ll implement a simple program both procedurally and with OOP:

Program Specification:

Procedural Implementation

# Open file and read lines into a list
file = open("text.txt")
lines = file.readlines()

# Print each line with line number
for i in range(len(lines)):
  print(str(i) + ": " + lines[i])

This uses a linear script with open data access.

OOP Implementation

class TextReader:
  def __init__(self, filename):
    self.filename = filename
    self.lines = self._load()

  def _load(self):
    file = open(self.filename)
    lines = file.readlines()
    return lines

  def print_lines(self):
    for i in range(len(self.lines)):
      print(str(i) + ": " + self.lines[i])

reader = TextReader("text.txt")

This encapsulates the data and methods into a TextReader class.

The OOP version is more modular and reusable but also more complex for this simple case. Procedural programming excels at linear scripts like this example.

For a more robust program with additional requirements and customizations, OOP would be better suited.


This guide provided an in-depth exploration of object-oriented programming vs procedural programming in Python. Key takeaways include:

Learning to leverage the strengths of each approach alongside the right Python tools and best practices will allow programmers to write maintainable, effective code. Mastering both paradigms unlocks the full power and versatility of Python.