Python Classes and Objects: __init__, self, Attributes, Methods
Learn Python classes and objects: the class keyword, __init__ and self, instance vs class attributes, methods, __repr__ and classmethod, with sales examples.
Picture a builder putting up a housing township on the Super Corridor in Indore. The architect draws one floor plan for a 2BHK flat: two bedrooms, a kitchen, a balcony facing east. That single drawing is used to build 120 flats.
Each flat is built from the same plan, yet each is separate. Flat 304 has blue walls and the Sharma family. Flat 512 has white walls and a home office. Painting one flat does not change any other, and nobody lives in the drawing itself.
In Python, the floor plan is a class. Each flat is an object (also called an instance). The wall colour and the family are the object's attributes, and things you can do in a flat, like "switch on the geyser", are its methods.
A class in Python is a blueprint, defined with the class keyword, that describes the attributes and methods its objects will have; an object is a single instance created from that class, with its own copy of the instance data.
This lesson opens the OOP section, after Python custom exceptions, where you already wrote small classes without knowing it. Examples target Python 3.12+.
What is a class and an object in Python?
You have used objects since your first program. Every value in Python is an object, and every object has a class. The number 5 is an instance of int, and a pandas DataFrame is an instance of the DataFrame class.
import pandas as pd
values = [5, "Indore", [1450, 980], {"city": "Ujjain"}]
for v in values:
print(repr(v), "is an instance of", type(v).__name__)
df = pd.DataFrame({"store": ["Palasia", "Rajwada"], "sales": [48200, 39100]})
print(type(df).__name__, "with", len(df), "rows")
print("upper() is a method of str:", "indore".upper())When you call df.head() or "indore".upper(), you are calling a method that the class defined. Writing your own class lets you create the same kind of thing for your own data: a store, an invoice, a sales target.
How do you create a class in Python?
You write class, a name in CapitalisedWords, and an indented body. Inside, the special method __init__ runs automatically each time you create an object. It receives the new, empty object as self and fills in its attributes.
class Store:
def __init__(self, name, monthly_target):
self.name = name
self.monthly_target = monthly_target
self.sales = [] # each store gets its own list
palasia = Store("Palasia", 50000)
rajwada = Store("Rajwada", 35000)
palasia.sales.append(12500)
print(palasia.name, palasia.monthly_target, palasia.sales)
print(rajwada.name, rajwada.monthly_target, rajwada.sales)
print(palasia is rajwada)Store("Palasia", 50000) does two things. Python first creates a blank Store object, then calls __init__(that_object, "Palasia", 50000). Inside __init__, self.name = name attaches an attribute to that particular object. The finished object is returned and stored in palasia.
One class, many objects: each object keeps its own copy of the instance attributes.
What is self in Python?
self is simply the first parameter of every regular method, and it refers to the object the method was called on. When you write palasia.record_sale(1200), Python turns it into Store.record_sale(palasia, 1200). The name self is a convention, not a keyword, but always use it.
Quick check
What does self refer to inside an instance method?
palasia.progress() is run as Store.progress(palasia), so self is palasia.
Adding methods to a class
A method is a function defined inside a class. Because it receives self, it can read and change that object's attributes. This is the real point of classes: the data and the code that works on it live together.
class Store:
def __init__(self, name, monthly_target):
self.name = name
self.monthly_target = monthly_target
self.sales = []
def record_sale(self, amount):
if amount <= 0:
raise ValueError("amount must be positive")
self.sales.append(amount)
def progress(self):
return round(sum(self.sales) / self.monthly_target * 100, 1)
palasia = Store("Palasia", 50000)
for amount in [12500, 8400, 15100]:
palasia.record_sale(amount)
print(f"{palasia.name}: {sum(palasia.sales)} sold, {palasia.progress()}% of target")
print(Store.progress(palasia)) # the same call, written the long wayNotice that record_sale checks its input before changing anything. Guarding an object's data inside its own methods keeps every store consistent, wherever in the program it is used.
Instance attributes vs class attributes
An attribute set on self is an instance attribute, unique to one object. An attribute written directly in the class body is a class attribute, shared by every object. Use class attributes for constants and for values that are truly the same for all instances.
class Store:
gst_rate = 0.18 # class attribute: shared
count = 0
def __init__(self, name):
self.name = name # instance attribute: per object
Store.count += 1
a, b = Store("Palasia"), Store("Rajwada")
print(a.gst_rate, b.gst_rate, Store.count)
a.gst_rate = 0.05 # creates an instance attribute on a only
print(a.gst_rate, b.gst_rate, Store.gst_rate)
print("a's own attributes:", vars(a))
print("b's own attributes:", vars(b))When you read a.gst_rate, Python looks in the object's own attributes first and then in the class. Assigning a.gst_rate = 0.05 does not change the class; it creates a new instance attribute that shadows the shared one, for a only.
Attribute lookup goes from the object to its class. Assignment through an object always writes to the object.
Quick check
A class has gst_rate = 0.18 as a class attribute. After a.gst_rate = 0.05, what is b.gst_rate for another instance b?
Assigning through a creates an instance attribute on a only. b still reads the class attribute.
Printing objects with __repr__
By default, printing an object shows something like <__main__.Store object at 0x7f...>, which is useless in a report. Define __repr__ to return a clear text form. Methods with double underscores, called dunder methods, are covered in depth in Python operator overloading.
class Store:
def __init__(self, name, city, target):
self.name, self.city, self.target = name, city, target
def __repr__(self):
return f"Store(name={self.name!r}, city={self.city!r}, target={self.target})"
@classmethod
def from_csv_line(cls, line):
name, city, target = line.split(",")
return cls(name.strip(), city.strip(), int(target))
stores = [Store.from_csv_line(l) for l in ["Palasia, Indore, 50000", "Freeganj, Ujjain, 22000"]]
print(stores)
print(stores[1])The @classmethod above is an alternative constructor. It receives the class as cls instead of an object, so it can build a new instance from a different input format, here a CSV line.
| Method type | First parameter | Typical use |
|---|---|---|
| Instance method | self (the object) |
Read or change one object's data |
@classmethod |
cls (the class) |
Alternative constructors like from_csv_line |
@staticmethod |
none | A helper that belongs with the class but uses neither |
When should a data analyst write a class?
Not every script needs one. A list of Python dictionaries and a few functions is often clearer. Reach for a class when the same group of data keeps travelling with the same operations, or when you need many objects that each track their own state.
Good signs: you pass the same four arguments to five functions, or you keep checking the same rules on dict keys. A Store, Invoice or Campaign class puts those rules in one place. For classes that mostly hold data, Python dataclasses remove most of the boilerplate.
Common mistakes with Python classes
- Forgetting
selfin a method definition.def progress():fails with aTypeErrorwhen called on an object. - Writing
name = nameinstead ofself.name = name. The value is stored in a local variable and lost. - Mutable class attributes.
sales = []in the class body is one list shared by all objects. Create lists in__init__. - Calling the method without brackets.
store.progressis the method itself;store.progress()runs it. - Changing a class attribute through an object.
a.count += 1creates an instance attribute. UseStore.count. - A class for everything. If it has one method and no state, a plain function is better.
Key takeaways
- A class is a blueprint; an object is one instance built from it.
__init__runs on creation and sets instance attributes onself.- Methods are functions in the class that receive the object as
self. - Class attributes are shared; instance attributes belong to one object.
- Lookup checks the object first, then the class.
- Define
__repr__so objects print clearly, and use@classmethodfor alternative constructors.
Next, reuse a class's code in another class with Python inheritance. Turning messy spreadsheet logic into small, testable classes is practised in the classroom data analytics programme taught in English and Hindi at Debugshala.
FAQ
What is the difference between a class and an object in Python?
A class is the definition, like a blueprint, that says which attributes and methods its objects have. An object is a concrete instance made from that class, holding its own data. Store is a class; Store("Palasia", 50000) creates an object. One class can produce any number of independent objects.
Why is self used in Python classes?
self gives a method access to the specific object it was called on, so it can read and change that object's attributes. Python passes it automatically: store.progress() becomes Store.progress(store). The name is a strong convention rather than a keyword, so other names work but confuse readers.
Is __init__ a constructor in Python?
__init__ a constructor in Python?It is usually called the constructor, though strictly it is an initialiser. Python creates the empty object first using __new__, then calls __init__ to fill in its attributes. You rarely need __new__. Put all your setup, such as storing arguments and creating empty lists, inside __init__.
Do data analysts need object-oriented programming?
You can do a lot of analysis with functions and pandas alone, but you use objects constantly, since DataFrames, Series and models are all classes. Knowing OOP helps you read library documentation, organise larger scripts and pass coding interviews, where classes are a standard topic.
Where can I learn Python OOP in Indore?
Debugshala teaches Python, including classes and objects, as part of its data analytics course at the Old Palasia campus in Indore. Classes are in English and Hindi, fresh graduates and non-IT learners are welcome, and there is a free demo class. You can also test your class and object basics on Debugshala Test.
From the team behind this site
Go further with the Data Analytics Course at Debugshala
These tutorials are written by Debugshala, a training and placement institute at Old Palasia, Indore. The classroom course adds live mentoring, real projects and interview preparation.
- Offline classes at Old Palasia, Indore
- Free demo class before you pay
- Non-IT, fresher and year-gap friendly
- Placement assistance
700+ students placed · 200+ hiring partners · 4.9★ Google rating