Object-Oriented Programming in Python
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 coursesInheritance: 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 needsselfas its first parameter, and you access attributes viaself.x. Leaving it out causes aTypeError. - Confusing the class with an object:
Dogis 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 coursesInstructor, Infoplanet
Kedar Kabra teaches Python at Infoplanet, helping beginners become confident programmers through hands-on, project-first practice.
Related guides
Dictionaries in Python
Understand Python dictionaries — storing data as key-value pairs — including adding, accessing, updating, looping, and safely reading values with .get().
Exception Handling in Python
Handle errors gracefully in Python with try, except, else, and finally — so your program responds to problems instead of crashing.
File Handling in Python
Read from and write to files in Python using with open() — covering file modes, reading line by line, appending, and safe file handling.
