Object-Oriented Programming in Python

    Kedar Kabra4 min readUpdated

    Object-Oriented Programming (OOP) lets you bundle data and the actions on that data into one unit called a class. From a class you create objects. Here's a tiny class in action:

    class Dog:
        def __init__(self, name):
            self.name = name        # store the dog's name
    
        def bark(self):
            return f"{self.name} says woof!"
    
    # Create an object from the class
    my_dog = Dog("Bruno")
    print(my_dog.bark())            # Bruno says woof!
    

    A class is like a blueprint; an object is a thing built from it. Let's unpack the pieces.

    Classes and objects

    A class defines what its objects will look like and do. An object (also called an instance) is a specific thing made from that blueprint:

    class Student:
        def __init__(self, name, marks):
            self.name = name        # attribute: data the object holds
            self.marks = marks
    
    # Two separate objects from the same class
    asha = Student("Asha", 85)
    ravi = Student("Ravi", 72)
    
    print(asha.name, asha.marks)    # Asha 85
    print(ravi.name, ravi.marks)    # Ravi 72
    

    Each object keeps its own copy of the data.

    The init method and self

    __init__ is a special method that runs automatically when you create an object. It sets up the object's starting data. The self parameter refers to the object being created:

    class Circle:
        def __init__(self, radius):
            # 'self.radius' belongs to this specific object
            self.radius = radius
    
        def area(self):
            # Methods use self to reach the object's data
            return 3.14159 * self.radius ** 2
    
    c = Circle(5)
    print(c.area())     # 78.53975
    

    You don't pass self yourself — Python supplies it automatically. Inside any method, self.something reaches that object's own data.

    Methods: functions inside a class

    A method is a function defined inside a class. It almost always takes self as its first parameter so it can access the object's attributes:

    class BankAccount:
        def __init__(self, owner, balance=0):
            self.owner = owner
            self.balance = balance
    
        def deposit(self, amount):
            self.balance += amount
    
        def show_balance(self):
            print(f"{self.owner}'s balance: {self.balance}")
    
    account = BankAccount("Meena", 100)
    account.deposit(50)
    account.show_balance()     # Meena's balance: 150
    

    Want to learn this properly?

    Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.

    Browse courses

    Inheritance: building on a class

    Inheritance lets one class reuse and extend another. The child class gets everything from the parent, and can add or override behaviour:

    class Animal:
        def __init__(self, name):
            self.name = name
    
        def speak(self):
            return "Some sound"
    
    # Cat inherits from Animal
    class Cat(Animal):
        def speak(self):            # override the parent's method
            return f"{self.name} says meow"
    
    generic = Animal("Creature")
    kitty = Cat("Whiskers")
    
    print(generic.speak())    # Some sound
    print(kitty.speak())      # Whiskers says meow
    

    Cat reused Animal's __init__ (so it still has a name) but gave its own version of speak().

    A complete example

    # Model a simple shopping cart
    
    class Cart:
        def __init__(self):
            self.items = []          # each cart starts empty
    
        def add(self, product, price):
            self.items.append((product, price))
    
        def total(self):
            # Sum the price of every item
            return sum(price for product, price in self.items)
    
    cart = Cart()
    cart.add("Pen", 20)
    cart.add("Notebook", 60)
    print(f"Items: {len(cart.items)}")   # Items: 2
    print(f"Total: {cart.total()}")      # Total: 80
    

    Common mistakes

    • Forgetting self: Every method needs self as its first parameter, and you access attributes via self.x. Leaving it out causes a TypeError.
    • Confusing the class with an object: Dog is the blueprint; Dog("Bruno") creates an object. You call methods on objects, not on the class directly.
    • Writing __init__ with one underscore: It's two underscores on each side: __init__. With one underscore it won't run automatically.
    • Setting attributes outside __init__ and expecting them everywhere: Define your core attributes in __init__ so every object has them from the start.
    • Overusing inheritance: Not everything needs a parent class. Use inheritance only when there's a genuine "is-a" relationship (a Cat is an Animal).

    FAQ

    What's the difference between a method and a function? A method is just a function that belongs to a class and usually takes self. A plain function lives on its own outside any class.

    Why is OOP useful? It groups related data and behaviour together, making large programs easier to organise, reuse, and maintain.

    What are dunder methods? Methods with double underscores like __init__ and __str__ are "dunder" (double-underscore) methods that Python calls automatically in special situations.


    OOP builds directly on Functions in Python, so be solid there first. You'll also store object data using Dictionaries in Python. Explore more on the Python learning hub.

    Want to learn this properly? Join the waitlist for our Python course — taught in Jalgaon, beginner-friendly.

    Want to learn this properly?

    Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.

    Browse courses
    Kedar Kabra

    Instructor, Infoplanet

    Kedar Kabra teaches Python at Infoplanet, helping beginners become confident programmers through hands-on, project-first practice.

    Related guides