What is a Python Decorator?
Muhammad Atif Iqbal

Muhammad Atif Iqbal @atifwattoo

About: AI Engineer with a software engineering background, skilled in Python, TensorFlow, PyTorch, FastAPI, Flask, Django ReactJS, and NextJS. Expert in building scalable AI models and applications.

Location:
Lahore, Pakistan
Joined:
Mar 23, 2024

What is a Python Decorator?

Publish Date: Mar 18
5 0

📌 What is a Python Decorator?

A Python decorator is a function that modifies another function or class without changing its original code.

READ complete article on this

It adds extra functionality (e.g., logging, authentication, caching) to functions or methods.

Uses the @decorator_name syntax to wrap a function.


✅ Basic Example of a Python Decorator

📌 Without a decorator (Manual way):

def uppercase_decorator(func):
    def wrapper():
        result = func()
        return result.upper()
    return wrapper

def say_hello():
    return "hello world"

# Manually applying decorator
say_hello = uppercase_decorator(say_hello)

print(say_hello())  # Output: "HELLO WORLD"
Enter fullscreen mode Exit fullscreen mode

Problem: We have to manually wrap say_hello inside uppercase_decorator.


📌 With a decorator (Cleaner way):

def uppercase_decorator(func):
    def wrapper():
        result = func()
        return result.upper()
    return wrapper

@uppercase_decorator  # ✅ This automatically applies the decorator
def say_hello():
    return "hello world"

print(say_hello())  # Output: "HELLO WORLD"
Enter fullscreen mode Exit fullscreen mode

Why is this better?

  • Less manual wrapping.
  • Easier to read and maintain.

✅ How Decorators Work (Step-by-Step)

@uppercase_decorator
def say_hello():
    return "hello world"
Enter fullscreen mode Exit fullscreen mode

1️⃣ Python sees @uppercase_decorator and applies it to say_hello.

2️⃣ uppercase_decorator(say_hello) is called automatically.

3️⃣ It returns the wrapper() function that modifies say_hello() output.

4️⃣ say_hello() now returns "HELLO WORLD" instead of "hello world".


✅ Real-World Examples of Decorators

🔹 Example 1: Logging Decorator

def log_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__} with {args} {kwargs}")
        result = func(*args, **kwargs)
        print(f"{func.__name__} returned {result}")
        return result
    return wrapper

@log_decorator
def add(a, b):
    return a + b

add(5, 3)
Enter fullscreen mode Exit fullscreen mode

💡 Output:

Calling add with (5, 3) {}
add returned 8
Enter fullscreen mode Exit fullscreen mode

Why Use This?

  • Automatically logs function calls and results without modifying the function itself.

🔹 Example 2: Authentication Decorator in FastAPI

from fastapi import FastAPI, Depends, HTTPException

app = FastAPI()

def auth_required(func):
    def wrapper(username: str):
        if username != "admin":
            raise HTTPException(status_code=403, detail="Unauthorized")
        return func(username)
    return wrapper

@app.get("/secure-data")
@auth_required  # ✅ Protects this route
def secure_data(username: str):
    return {"message": "Secure data accessed!"}

# Now only "admin" can access this route
Enter fullscreen mode Exit fullscreen mode

Why Use This?

  • Ensures only authenticated users can access certain API routes.

🔹 Example 3: Time Execution Decorator

import time

def time_it(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} took {end_time - start_time:.4f} seconds")
        return result
    return wrapper

@time_it
def slow_function():
    time.sleep(2)
    return "Finished"

slow_function()
Enter fullscreen mode Exit fullscreen mode

💡 Output:

slow_function took 2.0001 seconds
Enter fullscreen mode Exit fullscreen mode

Why Use This?

  • Measures execution time of a function (useful for performance optimization).

✅ Summary: Why Use Python Decorators?

Feature Why It's Useful?
Code Reusability Add extra behavior without modifying function code.
Readability @decorator_name makes it clear that the function is modified.
Flexibility Can be applied to multiple functions easily.
Used in Frameworks FastAPI, Django, Flask, TensorFlow all use decorators.

Comments 0 total

    Add comment