What you'll learn
Quick Answer
A class is a blueprint, and an object is a real thing built from that blueprint. In Python you define a class with the class keyword, set up each object's data in the __init__ method, and use self to refer to the object you are working with. Methods are functions inside the class that act on that data. Once you are comfortable, inheritance lets one class reuse and extend another.
What are classes and objects?
If you have written a few Python programs with variables, loops, and functions, the next big idea to learn is object-oriented programming, or OOP. Understanding python classes and objects is the doorway to OOP, and it is simpler than the name makes it sound.
Think of a class as a blueprint and an object as the actual thing built from that blueprint. The blueprint for a house is not a house you can live in; it is a plan. But from one blueprint you can build many houses. In the same way, one class can create many objects.
A common real example: the idea of a "Student" is a class. It describes what every student has (a name, a roll number) and what every student can do (introduce themselves). An individual student like Aarav or Priya is an object built from that class.
Why bother with classes at all?
You can write working Python without ever creating a class, so why bother? Classes help when your data and the actions on that data belong together. Instead of keeping a student's name in one variable, their marks in another, and separate functions that juggle them, a class bundles the data and the behaviour into one neat unit.
This matters most as programs grow. A game has players, enemies, and items. A shop has products, carts, and orders. Modelling each of these as a class keeps related code in one place, makes it reusable, and makes bugs easier to find. OOP is not always the right tool, but for anything you will describe as a "thing" with properties and actions, it fits naturally.
Define your first class with __init__
You create a class with the class keyword. Here is a small Student class:
class Student:
def __init__(self, name, roll_no):
self.name = name
self.roll_no = roll_no
def greet(self):
return f"Hi, I am {self.name}, roll number {self.roll_no}"
s = Student("Aarav", 12)
print(s.greet())
# Output: Hi, I am Aarav, roll number 12The special method __init__ (two underscores on each side) runs automatically every time you create an object. Its job is to set up the starting data for that object. When you write Student("Aarav", 12), Python calls __init__ with name = "Aarav" and roll_no = 12.
The line s = Student("Aarav", 12) is where an object is born. We say s is an instance of the Student class.
What does self actually mean?
Every method inside a class takes self as its first parameter, and beginners always ask why. self is simply the object you are currently working with. It lets each object keep its own data separate from every other object.
a = Student("Aarav", 12)
b = Student("Priya", 7)
print(a.name) # Aarav
print(b.name) # PriyaBoth objects share the same code, but a.name and b.name hold different values. Inside the class, self.name means "this particular object's name". You do not pass self yourself when calling a method; Python fills it in for you. That is why s.greet() works even though greet is defined as greet(self).
Instance attributes and methods
Data stored on an object is called an instance attribute (like name and roll_no). Functions defined inside the class are called methods. Methods usually read or change the object's attributes. Let us build something more useful, a bank account:
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self.balance = balance
def deposit(self, amount):
self.balance += amount
return self.balance
def withdraw(self, amount):
if amount > self.balance:
print("Not enough balance")
return self.balance
self.balance -= amount
return self.balance
account = BankAccount("Priya", 500)
account.deposit(200) # balance becomes 700
account.withdraw(1000) # prints: Not enough balance
print(account.balance) # 700Notice balance=0 in __init__. That is a default value, so you can create an account with no starting money by writing BankAccount("Priya"). Each method uses self.balance, which means the balance belongs to that one account and no other.
A first look at inheritance
Inheritance lets a new class reuse everything from an existing class and add its own extras. Suppose we want a savings account that earns interest. Instead of copying all the deposit and withdraw code, we build on top of BankAccount:
class SavingsAccount(BankAccount):
def __init__(self, owner, balance=0, rate=0.04):
super().__init__(owner, balance)
self.rate = rate
def add_interest(self):
self.balance += self.balance * self.rate
return self.balance
acc = SavingsAccount("Rahul", 1000)
acc.deposit(500) # inherited method, balance 1500
acc.add_interest() # 1500 + 4% = 1560.0
print(acc.balance) # 1560.0The line class SavingsAccount(BankAccount) means "SavingsAccount is a kind of BankAccount". It automatically gets deposit and withdraw for free. The call super().__init__(...) runs the parent's setup so we do not repeat it. This is where OOP starts to save real effort in bigger programs.
Common beginner mistakes
Forgetting self in a method
class Dog:
def bark(): # missing self
print("Woof")
Dog().bark()
# TypeError: bark() takes 0 positional arguments but 1 was givenEvery regular method needs self as its first parameter. The error message is confusing, but it almost always means a missing self.
Sharing a mutable value by accident
class Team:
members = [] # shared by ALL objects
def add(self, name):
self.members.append(name)
a = Team()
b = Team()
a.add("Sana")
print(b.members) # ['Sana'] -- surprise!Here members is a class attribute, so every object shares the same list. Almost always you want a fresh list per object, so create it inside __init__ instead:
class Team:
def __init__(self):
self.members = [] # each object gets its own list
Where to go next
Here is the short recommendation: start small. Write one class with __init__, a couple of attributes, and one or two methods. Create two objects from it and print their data. Once that feels natural, add a method that changes an attribute, then try inheritance with super().
A good order to learn next: the __str__ method (so print(object) shows something readable), class attributes versus instance attributes, and then encapsulation ideas like private-by-convention names with a leading underscore.
If you want a guided path with exercises, work through the free Python course on Priodemy, which covers functions before classes so the concepts build in the right order. The key takeaway: a class is a blueprint, an object is the real thing, self is that object talking about itself, and inheritance lets classes build on each other.
Frequently Asked Questions
What is the difference between a class and an object in Python?
A class is a blueprint that describes what data an object holds and what it can do. An object is a real, individual thing created from that blueprint. For example, Student is a class, while a specific student such as Aarav is an object (also called an instance) of that class. One class can create as many objects as you need.
What does self mean in a Python class?
self refers to the specific object a method is working on. It is how each object keeps its own data separate from other objects of the same class. You write self as the first parameter of every regular method, but you never pass it yourself when calling the method; Python fills it in automatically.
What is __init__ and do I always need it?
__init__ is a special method that runs automatically whenever you create an object. It sets up the starting values for that object's attributes. You do not always need it, but you should define it whenever an object needs some initial data, which is almost always. Without it, objects start with no attributes of their own.
When should I use inheritance?
Use inheritance when a new class is a more specific version of an existing one and should reuse its behaviour. A SavingsAccount is a kind of BankAccount, so it inherits deposit and withdraw and adds interest on top. If two classes are only loosely related, keep them separate instead of forcing inheritance.
Why do I get 'takes 0 positional arguments but 1 was given'?
This error usually means you forgot to add self as the first parameter of a method. Python passes the object as the first argument automatically, so a method defined without self receives one more argument than it expects. Add self to the method definition and the error goes away.
Are Python classes hard to learn for beginners?
Not really, once you get past the vocabulary. The core idea is just bundling data and functions together into a single unit. If you are already comfortable with functions and variables, you can learn the basics of classes, __init__, and self in an afternoon, then practise by modelling simple things like a student, a bank account, or a to-do item.
