Python

Python Decorators: A Comprehensive Guide

Python Decorators: A Comprehensive Guide

Python Decorators

Python decorators are a powerful feature that allows you to modify or extend the behavior of functions and methods without changing their original code. They are commonly used when additional functionality needs to be added to an existing function in a clean and reusable way.

Decorators are closely related to higher-order functions, inner functions, and Python’s ability to treat functions as first-class objects. In this guide, we will understand these concepts and explore practical decorator examples.

Python Decorators

What Are Decorators?

A decorator is a function that receives another function as an argument and returns a new function with additional or modified behavior.

In simple terms, a decorator allows you to add functionality to an existing function without directly modifying its implementation. Decorators are a form of metaprogramming because they can modify program behavior at runtime.

Understanding the Basics

Before learning decorators, it is useful to understand three important Python concepts: functions as first-class objects, inner functions, and higher-order functions.

Functions as First-Class Objects

Python treats functions as first-class objects. This means functions can be assigned to variables, passed as arguments, and returned from other functions.

def greet(message):
    print(message)

# Assign function to another variable
hello = greet

hello("Hello, World!")

Output:

Hello, World!

Inner Functions

An inner function is a function defined inside another function. Inner functions are frequently used when creating decorators.

def outer_function():
    print("This is the outer function.")

    def inner_function():
        print("This is the inner function.")

    inner_function()

outer_function()

Output:

This is the outer function.
This is the inner function.

Higher-Order Functions

A higher-order function either accepts another function as an argument or returns a function as its result.

def increment(x):
    return x + 1

def apply_function(func, value):
    return func(value)

result = apply_function(increment, 5)

print(result)

Output:

6

What Is a Decorator?

A decorator is essentially a higher-order function that takes a function, adds functionality around it, and returns the enhanced function.

Here is a simple decorator example:

def decorator(func):
    def wrapper():
        print("Before the function call")
        func()
        print("After the function call")

    return wrapper

@decorator
def say_hello():
    print("Hello!")

say_hello()

Output:

Before the function call
Hello!
After the function call

The @decorator syntax is a convenient way of applying a decorator. The following statement represents the same operation:

say_hello = decorator(say_hello)

Decorators with Parameters

Decorators can also be designed to accept parameters. This requires an additional function layer that receives the decorator’s arguments.

def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                func(*args, **kwargs)

        return wrapper

    return decorator

@repeat(3)
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")

Output:

Hello, Alice!
Hello, Alice!
Hello, Alice!

Common Use Cases for Decorators

1. Logging

Decorators can be used to display information about function calls, their arguments, and their returned results.

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

    return wrapper

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

add(5, 3)

Output:

Calling add with arguments (5, 3) and {}
add returned 8

2. Authentication

A decorator can also be used to check whether a user has permission to access a particular function.

def requires_auth(func):
    def wrapper(user):
        if user.get("authenticated"):
            return func(user)
        else:
            print("Authentication required!")

    return wrapper

@requires_auth
def view_profile(user):
    print(f"Welcome, {user['name']}!")

user = {
    "name": "Alice",
    "authenticated": True
}

view_profile(user)

Output:

Welcome, Alice!

3. Measuring Execution Time

Decorators can measure how long a function takes to execute.

import time

def timing(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()

        result = func(*args, **kwargs)

        end_time = time.time()

        print(
            f"{func.__name__} executed in "
            f"{end_time - start_time:.4f} seconds"
        )

        return result

    return wrapper

@timing
def compute():
    time.sleep(2)
    print("Computation complete!")

compute()

Output:

Computation complete!
compute executed in 2.0001 seconds

Advanced Decorators

Complete Advance AI Topics: Click Here
SQL Tutorial:
Click Here
YT:- DecodeIT

1. Class Decorators

A class that implements the __call__() method can be used as a decorator.

class Decorator:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print("Before the function call")

        result = self.func(*args, **kwargs)

        print("After the function call")

        return result

@Decorator
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")

Output:

Before the function call
Hello, Alice!
After the function call

2. Nesting Decorators

Python allows multiple decorators to be applied to the same function by stacking them.

def uppercase(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result.upper()

    return wrapper

def exclaim(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result + "!"

    return wrapper

@uppercase
@exclaim
def greet(name):
    return f"Hello, {name}"

print(greet("Alice"))

Output:

HELLO, ALICE!

Frequently Asked Questions

1. What is a decorator in Python?

A decorator is a function that receives another function and returns an enhanced version of that function.

2. Why are decorators used in Python?

Decorators are used to add functionality to existing functions without changing their original implementation.

3. What does the @ symbol mean in Python decorators?

The @ syntax provides a concise way to apply a decorator to a function.

4. Can decorators accept arguments?

Yes. Decorators can be designed to accept arguments by adding another function layer.

5. Can a class be used as a decorator?

Yes. A class can work as a decorator when it implements the __call__() method.

6. Can multiple decorators be applied to one function?

Yes. Multiple decorators can be stacked above a function, allowing several behaviors to be applied.

Conclusion

Python decorators provide a flexible way to extend and modify function behavior without changing the original function code. They are built around important Python concepts such as first-class functions, inner functions, and higher-order functions.

From logging and authentication to execution-time measurement, class decorators, and nested decorators, this feature provides a reusable approach for adding functionality to Python programs.

Keywords: Python Decorators, python decorator, python decorators with arguments, decorators in Python example, types of decorators in Python, python class decorator, python decorators for class methods, decorator function in Python, Python decorator tutorial, Python decorators W3Schools

Source Code Available

Interested in This Project?

Get the complete source code for this project at a very affordable price — perfect for your portfolio, college submission, or learning. Message us on WhatsApp and we'll get back to you instantly!

Full source code included Step-by-step setup guide Instant delivery on WhatsApp Instant reply on WhatsApp
Chat on WhatsApp

We usually reply within a few minutes

Leave a Reply

Your email address will not be published. Required fields are marked *

Chat with us