Master Guide to Classes and Objects in Python Blueprints and Instance Mechanics
Hello Everyone! Today we are exploring Object-Oriented Programming (OOP) by focusing on Classes and Objects.
A class is a blueprint or template for creating objects. Think of a class like a formal structural blueprint for a house: it defines where the rooms, windows, and doors go, but it isn’t a physical house itself. By establishing custom classes, you can model real-world concepts and build your own custom data types.
1. Core Mechanics: Blueprints vs. Instances
OOP breaks down complex systems into two essential structural elements:
- Attributes (The Data): Variables bound directly inside an object that store state properties. For a
Carclass, attributes might includecolor,brand, ormileage. - Methods (The Behavior): Functions defined inside a class that an object can perform. For a
Carclass, methods might includestart_engine(),drive(), orhonk().
General Layout Syntax
class Car:
# Class attributes (shared by all instances)
wheels = 4
# Methods define instance behaviors
def honk(self):
print("Beep beep!")
# Creating an instance object from the blueprint
my_car = Car()
print(type(my_car)) # Output: <class '__main__.Car'>
my_car.honk() # Output: Beep beep!
2. Demystifying self and Instance Scope
When you define a method inside a class, it requires a parameter named self as its very first argument.
What is
self? It is a pointer reference targeting the specific, individual object instance currently calling that method. It ensures that operations update the calling instance’s memory space rather than impacting all instances globally.
class Dog:
def eat(self):
# Binding a variable to self restricts its scope to the instance object
self.bone_count = 5
print("Eating...")
def bark(self):
# Accessing an instance attribute across different methods via self
print(f"Dog has {self.bone_count} bones left and says Woof!")
rex = Dog()
rex.eat()
rex.bark() # Output: Dog has 5 bones left and says Woof!
3. The __init__() Method (The Constructor)
The __init__() method is a special, built-in dunder method automatically executed the exact millisecond a new instance object is instantiated. Its main job is to initialize instance attributes with custom startup values.
class Dog:
species = "Canine" # Class Attribute
def __init__(self, name, age=2):
# Instance Attributes
self.dog_name = name
self.age = age
self.is_hungry = True
def bark(self):
print(f"{self.dog_name} says woof!")
# Instantiating objects with unique structural parameters
dog_a = Dog(name="Tom", age=4)
dog_b = Dog(name="Tuffy", age=3)
dog_a.bark() # Output: Tom says woof!
dog_b.bark() # Output: Tuffy says woof!
4. Attributes: Class vs. Instance
Understanding the scope separation between Class attributes and Instance attributes is essential for shared data state management:
- Instance Attributes: Declared inside methods using
self.attribute_name. These are completely unique to each individual object. - Class Attributes: Declared directly inside the main class body block, outside of any methods. These are shared globally by every single object spawned from that class.
class GST:
TAX_RATE = 18 # Class attribute shared across all items
def __init__(self, item_name):
self.name = item_name # Instance attribute unique to this specific item
milk = GST("Saras Milk")
bread = GST("Amul Bread")
print(f"{milk.name} tax: {milk.TAX_RATE}%") # Output: Saras Milk tax: 18%
# Modifying a Class Attribute updates the state globally for all instances
GST.TAX_RATE = 5
print(f"{bread.name} tax: {bread.TAX_RATE}%") # Output: Amul Bread tax: 5%
5. Method Execution Constraints
The presence or absence of the self parameter impacts how a method can be safely invoked:
class Demo:
def standard_method(self):
print("Instance method called.")
def standalone_method():
print("Static background logic called.")
# Instance Call behavior
obj = Demo()
obj.standard_method() # Valid: Implicitly passes 'obj' into 'self'
# obj.standalone_method() # Crashes! Passes 'obj' to a method expecting 0 arguments.
# Class Call behavior
Demo.standalone_method() # Valid: Called directly via the class blueprint name