A decorator in Python is a function that modifies the behavior of another function or class without changing its actual code.
📌 Think of it like wrapping a gift: the original gift (function) is inside, but you add some decoration (extra logic).
A closure is a function that remebers variables from its enclosing scope, even after the scope is finished.
🔹 Example
def outer():
message = "Hello Akash"
def inner():
print(message) # remembers "message"
return inner
func = outer()
func()
👉 Output: Hello Akash
This "remembering" ability allows decorators to wrap logic around another function.
def my_decorator(func):
def wrapper():
print("Before function execution")
func()
print("After function execution")
return wrapper
@my_decorator
def say_hello():
print("Hello, Akash")
say_hello()
Output:
Before function execution
Hello, Akash!
After function execution
Here:
@my_decorator
is syntactic sugar for say_hello = my_decorator(say_hello)
.say_hello
with extra logic.
def log_arguments(func):
def wrapper(*args, **kwargs):
print(f"Arguments were: {args} {kwargs}")
return func(*args, **kwargs)
return wrapper
@log_arguments
def add(a, b):
return a + b
print(add(5, 10))
Output:
Arguments were: (5, 10), {}
15
Another Example: Decorators with Arguments
def repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
for _, in range(n):
func(*args, **kwargs)
return wrapper
return decorator
@repeat(3)
def say_hello(name):
print(f"Hello {name}")
say_hello("Akash")
👉 Output:
Hello Akash
Hello Akash
Hello Akash
@staticmethod
@classmethod
@property
@functools.lru_cache
for (caching function results)@functools.wraps
(to preserve metadata of decorator function)Example:
from functools import lru_cache
@lru_cache(maxsize=100)
def fib(n):
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
print(fib(30))
👉 Efficient Fibonacci due to caching.
@login_required
)@lru_cache
from functools
)1. Django Authentication
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
@login_required
def dashboard(request):
return HttpResponse("Welcome to your dashboard")
2. Logging
def log(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with {args}, {kwargs}")
return func(*args, **kwargs)
return wrapper
3, Timing Functions
import time
def timing(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} took {end - start:.4f} sec")
return result
return wrapper
@timing
def slow_function():
time.sleep(2)
slow_function()
In Python, a decorator is a higher-order function that allows us to modify or enhance the behavior of another function or method without changing its code. Internally, it uses closures and higher-order functions.
For example, Django uses decorators like @login_required
for authentication. Python also provides built-in decorators like @staticmethod
, @classmethod
, and @property
. Decorators are heavily used for logging, caching, authentication, performance measurement, and reusable cross-cutting concerns.
Leave a Reply