DEV Community

Muhammad Atif Iqbal
Muhammad Atif Iqbal

Posted on

1 1 1 1 1

What is a Python Decorator?

πŸ“Œ 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.

API Trace View

How I Cut 22.3 Seconds Off an API Call with Sentry πŸ•’

Struggling with slow API calls? Dan Mindru walks through how he used Sentry's new Trace View feature to shave off 22.3 seconds from an API call.

Get a practical walkthrough of how to identify bottlenecks, split tasks into multiple parallel tasks, identify slow AI model calls, and more.

Read more β†’

Top comments (0)

Image of Timescale

πŸ“Š Benchmarking Databases for Real-Time Analytics Applications

Benchmarking Timescale, Clickhouse, Postgres, MySQL, MongoDB, and DuckDB for real-time analytics. Introducing RTABench πŸš€

Read full post β†’

πŸ‘‹ Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay