Expert · Object-oriented programming · topic 36 of 50 · 30 min
Classes and objects
Explanation
Why object-oriented programming?
So far you kept data in dictionaries and wrote separate functions that work on them. That works, but as a program grows it is easy to pass the wrong dictionary to the wrong function, or to forget a key. Object-oriented programming (OOP) keeps the data and the functions that belong to it together in one unit, called a class.
Your first class
class Student:
def __init__(self, name, roll_no):
self.name = name # attribute
self.roll_no = roll_no # attribute
self.marks = []
def add_mark(self, mark): # method
self.marks.append(mark)
def average(self):
if not self.marks:
return 0
return sum(self.marks) / len(self.marks)
priya = Student("Priya", 12) # create an object
priya.add_mark(88)
priya.add_mark(92)
print(priya.name, priya.average()) # Priya 90.0
rahul = Student("Rahul", 27) # a second, separate object
print(rahul.marks) # [] - his own list| Word | Meaning |
|---|---|
| class | The blueprint. Written with the class keyword; names use CapitalWords, like Student. |
| object / instance | One thing made from the class, like priya or rahul. |
| attribute | A variable that belongs to an object: priya.name |
| method | A function defined inside a class: priya.add_mark(88) |
| __init__ | The method Python runs automatically when you create an object, to set it up. |
| self | The object the method is working on right now. |
What self really is
When you write priya.add_mark(88), Python actually calls Student.add_mark(priya, 88). The object before the dot is passed in as the first parameter, and by convention we name that parameter self. That is how one method can work on many different objects.
A bank account that protects its data
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self.balance = balance
def deposit(self, amount):
if amount <= 0:
raise ValueError("Deposit must be positive")
self.balance += amount
return self.balance
def withdraw(self, amount):
if amount > self.balance:
raise ValueError("Not enough balance")
self.balance -= amount
return self.balance
acc = BankAccount("Anita", 1000)
acc.deposit(500)
acc.withdraw(300)
print(acc.owner, acc.balance) # Anita 1200
try:
acc.withdraw(5000)
except ValueError as e:
print("Error:", e)Class attributes and instance attributes
An instance attribute is set on self and belongs to one object. A class attribute is written directly inside the class body and is shared by all objects of that class. Use class attributes for values that are the same for everyone, like a school name or an interest rate.
class Student:
school = "Kendriya Vidyalaya" # class attribute: shared
count = 0
def __init__(self, name):
self.name = name # instance attribute: one per object
Student.count += 1
a = Student("Asha")
b = Student("Ravi")
print(a.school, b.school) # same for both
print(a.name, b.name) # different
print(Student.count) # 2When should you use a class?
- When several values always travel together (name, roll number, marks).
- When there are rules that must always be followed for that data (no overdraft).
- When you need many similar things (many accounts, many students).
- For a small one-off calculation, a plain function is still the simplest choice.
Watch the lesson
Classes and objects · 1/7
Welcome to object-oriented programming. In this lesson you will make your own types of objects using classes.
Prefer a video by a teacher? Find free videos on “python classes and objects for beginners self init” on YouTube ↗
In real life: A food delivery order
A food delivery app has thousands of orders at the same time. Each order has a restaurant, a list of items, a status and a total. The developers write one Order class with methods like add_item() and mark_delivered(), and every order in the app is an object made from it, so every order follows the same rules.
class Order:
def __init__(self, restaurant):
self.restaurant = restaurant
self.items = []
self.status = "placed"
def add_item(self, name, price):
self.items.append((name, price))
def total(self):
return sum(price for name, price in self.items)
order = Order("Sharma Dhaba")
order.add_item("Paneer butter masala", 240)
order.add_item("Tandoori roti x3", 60)
print(order.restaurant, order.status, order.total())Practice (0/3 done)
Write a class Product with __init__(self, name, price) that stores both values, and a method total(self, qty) that returns price times qty. Example: Product("Pen", 10).total(5) returns 50.
Write a class BankAccount with __init__(self, owner, balance=0), deposit(self, amount) and withdraw(self, amount). Both methods return the new balance. deposit raises ValueError if amount is 0 or less. withdraw raises ValueError if amount is more than the balance (and leaves the balance unchanged).
Write a class Ticket with a CLASS attribute sold = 0. Each time a Ticket(passenger) is created, store the passenger on the object and add 1 to Ticket.sold. Give each ticket a number attribute equal to the count at the time it was made (first ticket 1, second 2, ...).
Quick quiz
Read more (free)
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.