Python — Decorators, @classmethod, @staticmethod & the Three Types of Python Methods
Python functions can wrap other functions — and that a class has three completely different types of methods, each with a different…
Python — Decorators, @classmethod, @staticmethod & the Three Types of Python Methods
Python functions can wrap other functions — and that a class has three completely different types of methods, each with a different purpose.
Part 1 — Decorator
What Is a Decorator?
A decorator is a function that:
Takes another function as its argument
Wraps it — adds behavior before and/or after it runs
Returns a new function (the wrapper)
Decorator -> is a function
argument -> it takes a function
def my_fun(func): here func is source code
we do NOT change the original code
we EXTEND its functionality
Think of it like a gift wrapper. The gift (original function) stays the same inside. The wrapper (decorator) adds presentation around it.
How It Works — Step by Step
def my_decorator(xyz): # xyz = the original function being decorated
def wrapper():
print("Hello 1") # runs BEFORE the original function
xyz() # calls the original function
print("Hello 3") # runs AFTER the original function
return wrapper # returns the new wrapped function
@my_decorator # applies the decorator
def hello_counter():
print("Hello 2 ")
hello_counter()
# Output:
# Hello 1
# Hello 2
# Hello 3
What @my_decorator does: Writing @my_decorator above a function is exactly the same as writing:
hello_counter = my_decorator(hello_counter)
Python passes hello_counter into my_decorator, and replaces it with the returned wrapper.
Another Example:
def repeat(func):
def wrapper(value):
for i in range(3):
func(value)
return wrapper
@repeat
def greet(name):
print(f"Hello, {name}!")
greet("Ram")
# Output
# Hello, Ram!
# Hello, Ram!
# Hello, Ram!
When Are Decorators Used in Real Life?
**@classmethodand `@staticmethod`** — built-in Python decorators (covered below)
**@property** — turns a method into an attribute
Timing — measure how long a function takes
Logging — track every function call automatically
The Three Types of Methods in a Class:
Every method inside a class falls into one of three categories. Understanding the difference is essential for writing clean OOP code.
Method Type Decorator First Parameter Accesses
Instance method (none) self Instance data + class data
Class method @classmethod cls Class data only
Static method @staticmethod (none) Neither — utility only
Instance Method
The most common type. Takes self as the first parameter, giving it access to the specific object's data.
class Cat:
def __init__(self, name, age):
self.name = name
self.age = age
def describe(self): # instance method
return f"{self.name} is {self.age} years old"
def voice(self, sound): # instance method with extra param
return f"{self.name} says {sound}"
cat1 = Cat("Merry", 1)
cat1.describe() # 'Merry is 1 years old'
cat1.voice("Meow") # 'Merry says Meow'
Instance methods work with self — the specific object that called them.
Class Method
What Is a Class Method?
A class method is a method that:
Uses
**@classmethoddecorator**
Takes
**cls** (the class itself) as the first parameter — notself
Can access and modify class attributes that are shared across all objects
Is called on the class itself, not on an object:
ClassName.method()
@classmethod decorator
Factory method creation
cls -> refers to the class itself (like self refers to the object)
class Customer:
total_customer = 0 # class attribute — shared
total_customer_spent = 0 # class attribute — shared
def __init__(self, name, amount_spent):
self.name = name
self.amount_spent = amount_spent
Customer.total_customer += 1 # update class attr
Customer.total_customer_spent += amount_spent # update class attr
# Instance method — works on one customer
def customer_details(self):
return f"The name of the customer is {self.name} and s/he has spent NPR {self.amount_spent}"
# Class method — works on ALL customers
@classmethod
def get_total_customer(cls):
return f"Total number of customer is {cls.total_customer}"
# Class method — calculates class-level statistic
@classmethod
def avg_customer_spent(cls):
return f"Total average spent by the customer is {cls.total_customer_spent / cls.total_customer:.2f}"
customer1 = Customer("Ram", 1000)
customer2 = Customer("Gita", 2500)
customer3 = Customer("Shyam", 500)
total = Customer.get_total_customer()
avg = Customer.avg_customer_spent()
print(total) # Total number of customer is 3
print(avg) # Total average spent by the customer is 1333.33
Notice: Customer.get_total_customer() is called on the class, not on any specific customer object. It knows about all three customers because it accesses the class attribute total_customer.
Static Method
What Is a Static Method?
A static method is a method that:
Uses
**@staticmethoddecorator**
Takes no implicit first argument — no
self, nocls
Cannot access or modify class or instance state
Is just a regular utility function that lives inside the class for organizational purposes
@staticmethod decorator
does not take any implicit first argument (like self, cls)
Cannot access or modify the class state
class Customer:
def __init__(self, name, amount_spent):
self.name = name
self.amount_spent = amount_spent
def customer_details(self):
return f"The name of the customer is {self.name} and s/he has spent NPR {self.amount_spent}"
@staticmethod
def is_valid_account_type(account_type):
valid_account_type = ["Coffee products", "Tea Products", "Bakery Products"]
return account_type in valid_account_type # returns True or False
@staticmethod
def addition(x, y, z): # pure utility — no class/instance data needed
return x + y + z
Customer.is_valid_account_type("Coffee products") # True
Customer.is_valid_account_type("Dairy") # False
Customer.addition(2, 3, 4) # 9
The is_valid_account_type method doesn't need to know about any specific customer. It just validates whether a type is in the allowed list — pure logic. That's what static methods are for.
Instance Method vs @classmethod vs @staticmethod
class Employee:
company = "MY COMPANY" # class attribute
def __init__(self, name, salary):
self.name = name
self.salary = salary
# INSTANCE METHOD — accesses this specific employee
def get_details(self):
return f"{self.name} earns {self.salary}"
# CLASS METHOD — accesses company-level data
@classmethod
def get_company(cls):
return f"Company: {cls.company}"
# STATIC METHOD — pure utility, no company/employee data needed
@staticmethod
def is_valid_salary(salary):
return salary > 0
emp1 = Employee("Ram", 50000)
emp2 = Employee("Gita", 75000)
# Instance method — called on object
emp1.get_details() # Ram earns 50000
# Class method — called on class
Employee.get_company() # Company: MY COMPANY
# Static method — called on class (or object, both work)
Employee.is_valid_salary(50000) # True
Employee.is_valid_salary(-1000) # False 메타데이터
- post_id
- b7f65e5e9f8f
- slug
- python-decorators-classmethod-staticmethod-the-three-types-of-python-methods-b7f65e5e9f8f
- url
- https://medium.com/@dotsyko/python-decorators-classmethod-staticmethod-the-three-types-of-python-methods-b7f65e5e9f8f
- canonical_url
- https://medium.com/@dotsyko/python-decorators-classmethod-staticmethod-the-three-types-of-python-methods-b7f65e5e9f8f
- author_url
- https://medium.com/@dotsyko
- status
- ok
- fetched_at
- 2026-06-13 09:11:36