20 September 2026
Python OOP for Beginners: A Practical Guide to Classes and Objects
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.