All Posts

20 September 2026

Python OOP for Beginners: A Practical Guide to Classes and Objects

PythonOOPProgrammingBeginners

Object-Oriented Programming (OOP) is the point where most beginners stop writing scripts and start building software. If you can write a function in Python but freeze up at the word "class," this guide is for you.

Why OOP at All?

Procedural code (a long chain of functions operating on data) works fine for small scripts. It breaks down once your program has multiple related pieces of state — a user, an order, a game character — that all need to carry their own data and behavior together. OOP lets you bundle both into one unit: an object.

Classes and Objects

A class is a blueprint. An object is a specific thing built from that blueprint.

class Student:
    def __init__(self, name, marks):
        self.name = name
        self.marks = marks

    def has_passed(self):
        return self.marks >= 40

s1 = Student("Aditi", 78)
s2 = Student("Rohan", 32)

print(s1.has_passed())  # True
print(s2.has_passed())  # False

Student is the class. s1 and s2 are objects (instances) — each with its own name and marks, but sharing the same has_passed behavior.

The Four Pillars

1. Encapsulation — bundling data and the methods that act on it inside one object, and hiding internal details behind a clean interface.

class BankAccount:
    def __init__(self, balance=0):
        self.__balance = balance  # "private" by convention

    def deposit(self, amount):
        self.__balance += amount

    def get_balance(self):
        return self.__balance

2. Inheritance — a class can reuse and extend another class's behavior instead of duplicating it.

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

    def introduce(self):
        return f"Hi, I'm {self.name}"

class Teacher(Person):
    def __init__(self, name, subject):
        super().__init__(name)
        self.subject = subject

    def introduce(self):
        return f"{super().introduce()} and I teach {self.subject}"

3. Polymorphism — different classes can respond to the same method call in their own way.

class Dog:
    def speak(self):
        return "Woof"

class Cat:
    def speak(self):
        return "Meow"

for animal in [Dog(), Cat()]:
    print(animal.speak())

4. Abstraction — exposing only what's necessary and hiding implementation complexity, often using Python's abc module for enforced interfaces.

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        ...

class Circle(Shape):
    def __init__(self, r):
        self.r = r

    def area(self):
        return 3.1416 * self.r ** 2

A Common Beginner Mistake

Don't reach for a class just because you can. If a function with plain arguments solves the problem, use a function. Reach for a class when you have state that needs to persist across multiple method calls on the same entity — that's the real signal OOP is the right tool.

Where to Go Next

Once classes and inheritance feel natural, look into @classmethod and @staticmethod, dataclasses for reducing boilerplate, and composition ("has-a" relationships) as an alternative to deep inheritance chains, which tends to age better in larger codebases.

FAQ

Common Questions

Neither is universally better. Use functions for stateless logic, and classes when you need to bundle data with behavior that changes over time on the same object.

Python OOP for Beginners: A Practical Guide to Classes and Objects — CodeWithMunnaX