Python provides three types of methods in a class: Instance Methods, Class Methods, and Static Methods. Each serves a different purpose and is used based on the requirement. In this article, we’ll explore these methods with examples to understand their differences and use cases.
Table of Contents

Instance Methods
Instance methods are the most commonly used methods in a class. They have access to both instance variables (attributes) and class variables. They require an instance of the class to be called.
Characteristics:
- Defined using def with self as the first parameter.
- Can modify the object’s state (instance attributes).
- Can access and modify class-level data.
Example 1: Basic
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"Hello, my name is {self.name} and I am {self.age} years old."
# Creating an instance
person = Person("Alice", 25)
print(person.greet()) # Output: Hello, my name is Alice and I am 25 years old.
PythonExample 2 A: Instance method accessing class variables
class MyClass:
class_var = 10 # This is a class variable
def __init__(self, value):
self.instance_var = value # Instance variable
def print_vars(self):
print("Class Variable (via class):", MyClass.class_var) #correct way
print("Class Variable (via self):", self.class_var) #working, but don't use like this
print("Instance Variable:", self.instance_var)
obj = MyClass(5)
obj.print_vars()
PythonExample 2 B Strange
class my_class:
counter = 0
def abc(self):
self.counter+=1 #refering to instance variable
@classmethod
def xyz(cls):
print(cls.counter)
@staticmethod
def d():
print(my_class.counter)
obj1 = my_class()
obj2 = my_class()
obj1.abc()
obj2.abc()
obj1.xyz()
my_class().d()
'''
0
0
'''
PythonWhy
- Above code, does not modify the class variable counter, while in code 2A its refering to class variable
- Instead, it creates an instance variable counter for self (i.e., obj1 or obj2) if it doesn’t already exist, and modifies that.
Reason
- 2A: Accessing self.class_var → Python looks up the class if it’s not on the instance.
- 2B: Assigning to self.class_var = … → Python creates an instance attribute, shadowing the class one.
So to avoid confusion alway use class_name.class_variable
When to Use:
- When you need to work with instance attributes.
- When the method behavior depends on the individual object.
Class Methods
Class methods are used when we need to modify or access class-level attributes rather than instance attributes. They are bound to the class and receive cls (class reference) as the first parameter instead of self.
Characteristics:
- Defined using @classmethod decorator
- Takes cls as the first parameter
- Can access and modify class attributes but cannot modify instance attributes
- shared across all instances
Example:
class Car:
wheels = 4 # Class attribute
def __init__(self, brand):
self.brand = brand
@classmethod
def set_wheels(cls, count):
cls.wheels = count # Modifies class attribute
@classmethod
def get_wheels(cls):
return f"All cars have {cls.wheels} wheels."
# Modifying class attribute using class method
Car.set_wheels(6)
print(Car.get_wheels()) # Output: All cars have 6 wheels.
PythonWhen to Use:
- When a method needs to operate on class variables rather than instance variables.
- When alternative constructors are needed.
Alternative constructor:
A class method can be used as an alternative constructor to process the data and create an instance.
class Employee:
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def alternative(cls, name, age):
return cls(name, age)
emp_cons = Employee("Sam",45)
emp_alter = Employee.alternative("John",30)
print(type(emp_cons)) #<class '__main__.Employee'>
print(type(emp_alter)) #<class '__main__.Employee'>
PythonStatic Methods
Static methods are independent of both class and instance attributes. They are used when we don’t need to modify class or instance attributes but still want to keep related functionality inside the class.
Characteristics:
- Defined using @staticmethod decorator.
- Do not take self or cls as the first parameter.
- Can be called on an instance or class.
Example 1: Basic
class MathOperations:
@staticmethod
def add(x, y):
return x + y
@staticmethod
def multiply(x, y):
return x * y
# Calling static methods
print(MathOperations.add(5, 3)) # Output: 8
print(MathOperations.multiply(4, 6)) # Output: 24
PythonExample 2: Static methods can be called on an instance or class.
class MyClass:
@staticmethod
def greet():
print("Hello from static method!")
# Calling on the class
MyClass.greet()
# Calling on an instance
obj = MyClass()
obj.greet()
PythonWhen to Use:
- When a method does not depend on instance or class attributes.
- For utility functions related to the class but do not require access to class/instance data.
Key Differences
Feature | Instance Method | Class Method | Static Method |
---|---|---|---|
Bound to | Instance | Class | Neither |
First Parameter | self (instance) | cls (class) | No self or cls |
Can Modify Instance Attributes? | Yes | No | No |
Can Modify Class Attributes? | Yes | Yes | No |
Called Using | Instance | Instance or Class | Instance or Class |
Real life Example
Bank Account System
- Instance Method – Working with Object Attributes
- Imagine a Bank Account where each customer has their own balance and can deposit or withdraw money.
class BankAccount:
def __init__(self, account_holder, balance=0):
self.account_holder = account_holder
self.balance = balance # Instance attribute
def deposit(self, amount):
self.balance += amount
return f"Deposited {amount}. New Balance: {self.balance}"
def withdraw(self, amount):
if amount > self.balance:
return "Insufficient funds!"
self.balance -= amount
return f"Withdrawn {amount}. Remaining Balance: {self.balance}"
# Real-Life Usage
account1 = BankAccount("Alice", 1000)
print(account1.deposit(500)) # Deposited 500. New Balance: 1500
print(account1.withdraw(2000)) # Insufficient funds!
print(account1.withdraw(300)) # Withdrawn 300. Remaining Balance: 1200
PythonWhy use an instance method?
- Each account has its own balance.
- The deposit and withdraw methods modify the account’s balance, which is unique for every customer.
Counting Total Employees in a Company
- Class Method – Managing Shared Data
- Imagine a company where we need to track the total number of employees.
class Employee:
total_employees = 0 # Class attribute (shared by all instances)
def __init__(self, name):
self.name = name
Employee.total_employees += 1 # Updating shared data
@classmethod
def get_total_employees(cls):
return f"Total Employees: {cls.total_employees}"
# Real-Life Usage
emp1 = Employee("John")
emp2 = Employee("Emma")
emp3 = Employee("Liam")
print(Employee.get_total_employees()) # Total Employees: 3
# We can use object as well
print(emp3.get_total_employees()) # Total Employees: 3
PythonWhy use a class method?
- total_employees is shared across all instances.
- get_total_employees() provides a way to access and modify class-level data.
Example: Validating Emails for User Registration
- Static Method – Utility Functions Inside a Class
- Imagine an application where we need to validate user emails before creating an account.
import re
class User:
def __init__(self, username, email):
if not self.validate_email(email):
raise ValueError("Invalid Email Format!")
self.username = username
self.email = email
@staticmethod
def validate_email(email):
return re.match(r"[^@]+@[^@]+\.[^@]+", email)
# Real-Life Usage
try:
user1 = User("alice", "alice@example.com") # Valid email
print("User registered successfully!")
except ValueError as e:
print(e)
try:
user2 = User("bob", "bob@invalid-email") # Invalid email
except ValueError as e:
print(e) # Output: Invalid Email Format!
PythonWhy use a static method?
- It doesn’t need to modify or access any attributes (instance or class).
- It’s a self-contained utility function inside the class.
- Keeps email validation logic inside the User class, maintaining code organization.
All in one
class Employee:
company_name = "TechCorp" # Class variable shared by all instances
employee_count = 0 # Class variable to track number of employees
def __init__(self, name, salary):
self.name = name # Instance variable
self.salary = salary # Instance variable
Employee.employee_count += 1 # Update class variable
# Instance method: uses 'self', can access instance and class variables
def show_details(self):
print(f"Name: {self.name}")
print(f"Salary: ${self.salary}")
print(f"Company: {Employee.company_name}") # Access class variable
print()
# Class method: uses 'cls', can access/modify class variables only
@classmethod
def update_company(cls, new_name):
print(f"Changing company name from {cls.company_name} to {new_name}")
cls.company_name = new_name
# Static method: does not use 'self' or 'cls', utility method
@staticmethod
def is_valid_salary(salary):
return salary > 0
# --- Using the class ---
# Check salary using static method (without creating object)
print("Is 5000 a valid salary?", Employee.is_valid_salary(5000))
print("Is -1000 a valid salary?", Employee.is_valid_salary(-1000))
print()
# Create objects (instances)
emp1 = Employee("Alice", 5000)
emp2 = Employee("Bob", 6000)
# Use instance method
emp1.show_details()
emp2.show_details()
# Use class method to update company name
Employee.update_company("InnoTech")
# Show updated class variable via instance method
emp1.show_details()
emp2.show_details()
# Show total number of employees (accessing class variable directly)
print(f"Total employees: {Employee.employee_count}")
PythonOutput
Is 5000 a valid salary? True
Is -1000 a valid salary? False
Name: Alice
Salary: $5000
Company: TechCorp
Name: Bob
Salary: $6000
Company: TechCorp
Changing company name from TechCorp to InnoTech
Name: Alice
Salary: $5000
Company: InnoTech
Name: Bob
Salary: $6000
Company: InnoTech
Total employees: 2
PythonParameter cls, self
cls in class Method
- cls is a convention used to represent the class itself in class methods.
- Just like self refers to the instance of a class, cls refers to the class when working with class methods.
- It allows accessing and modifying class-level attributes.
- This allows you to modify instance creation, such as implementing a singleton pattern or controlling subclass instantiation.
self in Instance Method
- Instance methods operate on a specific instance of a class.
- The first parameter, self, represents the instance itself, giving access to instance attributes and methods.
- Without self, Python wouldn’t know which instance’s attributes or methods to modify.
No self or cls in Static Methods
- Static methods do not operate on an instance or class; they are just functions inside a class.
- They don’t have access to instance (self) or class (cls) attributes unless explicitly passed.
- Defined using @staticmethod, they are useful for utility functions that logically belong to the class but don’t need access to the class or instance state.
Why cls? , why not use self in class method?
Because the instance doesn’t exist yet, but the class does.
__new__
- __new__ is a special method that is called before __init__.
- It is responsible for creating and returning a new instance of the class.
- It’s a static method under the hood, and is rarely overridden unless you’re doing something special (like implementing singletons, immutability, or subclassing immutable types like int or str).
When is __new__ used?
- When customizing object creation (before initialization).
- When subclassing immutable types like str, int, tuple, etc.
- In design patterns (like Singleton or Factory).
Flow of Object Creation
- __new__ is called → it creates and returns a new object.
- __init__ is called → it initializes that object.
Example: Basic
class Demo:
def __new__(cls, *args, **kwargs):
print("Inside __new__")
instance = super().__new__(cls)
return instance
def __init__(self, value):
print("Inside __init__")
self.value = value
obj = Demo(42)
'''
Inside __new__
Inside __init__
'''
PythonExample: Customizing Object Creation
class LimitInstances:
count = 0
limit = 2
def __new__(cls, *args, **kwargs):
if cls.count >= cls.limit:
print("Limit reached. No more instances allowed.")
return None
cls.count += 1
return super().__new__(cls)
def __init__(self, name):
self.name = name
print(f"Instance created: {self.name}")
a = LimitInstances("A") # Allowed
b = LimitInstances("B") # Allowed
c = LimitInstances("C") # Blocked
'''
Instance created: A
Instance created: B
Limit reached. No more instances allowed.
'''
PythonConclusion
Understanding these three types of methods in Python helps in writing cleaner and more efficient code. Instance methods are used for working with object attributes, class methods work with class attributes, and static methods provide utility functionality that doesn’t rely on instance or class attributes.
- Use instance methods when working with object-specific data.
- Use class methods when working with shared data across all instances.
- Use static methods for utility functions that don’t depend on instance or class attributes.
1 thought on “Class Methods, Static Methods, and Instance Methods in Python”