Skip to content

Expert · Object-oriented programming · topic 36 of 50 · 30 min

Classes and objects

Explanation

A class is a blueprint that describes what data a thing has and what it can do. An object (also called an instance) is one real thing made from that blueprint. __init__ sets up each new object, and self means "this particular object".

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.

Think of it like this: A class is like the blank admission form printed by a school: it has boxes for name, class and roll number. Each filled-in form is an object. There is one design of the form, but hundreds of filled forms, each with its own details.

Your first class

python
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
Each object has its own copy of name, roll_no and marks.
WordMeaning
classThe blueprint. Written with the class keyword; names use CapitalWords, like Student.
object / instanceOne thing made from the class, like priya or rahul.
attributeA variable that belongs to an object: priya.name
methodA function defined inside a class: priya.add_mark(88)
__init__The method Python runs automatically when you create an object, to set it up.
selfThe 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.

Careful: Forgetting self is the most common mistake. If you write def average(): without self, calling priya.average() gives a TypeError saying the method takes 0 positional arguments but 1 was given. Inside methods, write self.marks, not just marks.

A bank account that protects its data

python
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)
The rules (no negative deposits, no overdraft) live inside the class, so every account follows them.

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.

python
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)        # 2
Change a shared value through the class name: Student.count, not self.count.
Careful: Never use a list or dictionary as a class attribute for per-object data. If marks = [] is written in the class body, every Student shares ONE list, and adding a mark to one student adds it to all. Create lists inside __init__ with self.marks = [].
Tip: You can still use print(vars(priya)) to see all of an object's attributes as a dictionary. It is handy while debugging.

When 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

Classes and objects

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.

python
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())
One class, as many orders as you need.

Practice (0/3 done)

Task 1 · Code · Python

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.

Task 2 · Code · Python

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).

Task 3 · Code · Python

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

Question 1

1.What is the difference between a class and an object?

Question 2

2.When does __init__ run?

Question 3

3.In priya.add_mark(88), what is self inside add_mark?

Question 4

4.What happens if marks = [] is written in the class body and each student appends to self.marks?

Question 5

5.Which line correctly sets an attribute inside __init__?

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.

← Previous: Project: password strength checker