Classes and objects
Part of the free LogicWiz Python course, Module 9: Object-oriented programming. The examples and practice run in the app.
Aarav keeps the canteen menu in three lists: names, prices and stock. He sorted prices once, and suddenly Samosa cost ₹60 and Dosa ₹15. There has to be a way to keep a dish's name and price glued together.
You'll learn to
- Write a class with `__init__` and make objects from it
- Understand what `self` really is
- Add methods that read and change an object
- Control how an object prints with `__str__` and `__repr__`
Learn
One thing instead of three lists
A class bundles data (a dish's name and price) with the actions on that data (work out a total, give a discount). Think of a class as the mould for a samosa. Every samosa you press out of it is an object (also called an instance). One class, many objects, and each object keeps its own values.
This idea, data and behaviour living together, is what object-oriented programming (OOP) means.
Your first class
class Item:
def __init__(self, name, price):
self.name = name
self.price = price
samosa = Item("Samosa", 15)
chai = Item("Chai", 10)
print(samosa.name, samosa.price)
print(chai.name, chai.price)
Step through it: each Item(...) call makes a new object, and self.name = name puts a name label on that object.
What `__init__` and `self` do
Item("Samosa", 15) does two jobs. First Python makes a new, empty object. Then it calls __init__(that_object, "Samosa", 15).
The first parameter, self, is that new object. self.name = name attaches a name to it. Without self., name is just a local variable that disappears when __init__ ends.
Exams call __init__ the constructor. Strictly it's the initialiser: lesson 9.6 shows who really builds the object.
Methods are functions that receive self
class Item:
def __init__(self, name, price):
self.name = name
self.price = price
def total(self, qty):
return self.price * qty
def discount(self, percent):
self.price = self.price - self.price * percent / 100
samosa = Item("Samosa", 20)
print(samosa.total(3))
print(Item.total(samosa, 3)) # the same call, written out in full
samosa.discount(10)
print(samosa.price)
samosa.total(3) is shorthand for Item.total(samosa, 3). That's where self comes from: Python passes the object for you.
Forgot self? Writing def total(qty): inside a class gives TypeError: total() takes 1 positional argument but 2 were given, because Python passed the object and 3. And name = name inside __init__ (no self.) silently does nothing: the object never gets a name.
__str__ and __repr__
class Item:
def __init__(self, name, price):
self.name = name
self.price = price
def __str__(self):
return f"{self.name} - Rs {self.price}"
def __repr__(self):
return f"Item({self.name!r}, {self.price})"
samosa = Item("Samosa", 15)
print(samosa) # print uses __str__
print([samosa]) # a list shows its items with __repr__
print(repr(samosa))
Delete both methods and run again: you get something like <__main__.Item object at 0x10a3f2d50>. That is the default.
__str__ vs __repr__
| str | repr |
|---|---|
| For people: a friendly line | For programmers: unambiguous, ideally valid Python |
| Used by print(x) and str(x) | Used by repr(x), the shell, and inside lists/dicts |
| Samosa - Rs 15 | Item('Samosa', 15) |
| Falls back to repr if missing | Falls back to <... object at 0x... |
Semester papers (AKTU, VTU, Anna, JNTU) ask: define class and object; what is self; write a class Student with a constructor and a method to display details. The full-marks pattern: write the class, create two objects, call the method on each, and show the output.
In one line
A class is a blueprint; __init__ fills each new object through self; print uses __str__, lists and the shell use __repr__.
Interview corner
What is the difference between a class and an object?
A class is a blueprint that defines attributes and methods; an object is one concrete instance made from it, with its own attribute values. Item is the class; samosa = Item("Samosa", 15) is an object. Many objects can come from one class.
What is `self` in Python? Is it a keyword?
self is the first parameter of an instance method and refers to the object the method was called on: obj.m(x) runs Cls.m(obj, x). It is not a keyword, only a strong convention; any name would work, but always use self.
What is the difference between `__str__` and `__repr__`?
__str__ gives a readable string for end users and is used by print() and str(). __repr__ gives an unambiguous, developer-facing string (ideally one that recreates the object) and is used by repr(), the REPL and containers like lists. If only __repr__ is defined, print falls back to it.
Is `__init__` a constructor?
Informally, yes. Strictly, __new__ constructs (allocates) the object and __init__ initialises the already-created object. __init__ must return None.