Decorators

Decorators are a way to modify or enhance the behavior of functions or classes without directly modifying their source code. Decorators allow us to wrap a function or class with another function, which can add functionality, modify inputs or outputs, or perform other operations.

Decorators are defined using the @ symbol followed by the name of the decorator function. Here's an example:

def my_decorator(func):
    def wrapper():
        print("Before function execution")
        func()
        print("After function execution")
    return wrapper

@my_decorator
def my_function():
    print("Inside the function")

my_function()

In this code, we define a decorator function called my_decorator. The decorator takes a function as an argument, defines a new function called wrapper, and returns the wrapper function. The wrapper function adds functionality before and after the original function is executed.

We apply the decorator to the my_function using the @ symbol. This means that whenever we call my_function, it will be wrapped with the my_decorator function.

When we run the code, the output will be:

Before function execution
Inside the function
After function execution

The decorator function allows us to modify the behavior of my_function without changing its source code. We can add additional functionality, such as logging, timing, or input validation, by simply applying the decorator.

Decorators can also accept arguments, allowing for more flexibility. Here's an example:

def repeat(n):
    def decorator(func):
        def wrapper():
            for _ in range(n):
                func()
        return wrapper
    return decorator

@repeat(3)
def greet():
    print("Hello!")

greet()

In this code, we define a decorator function called repeat that takes an argument n. The repeat decorator returns another decorator function, which in turn returns the wrapper function. The wrapper function repeats the execution of the original function n times.

We apply the decorator to the greet function using @repeat(3), which means that greet will be executed three times when called.

When we run the code, the output will be:

Hello!
Hello!
Hello!

Decorators are a powerful feature in Python that allow us to modify the behavior of functions or classes in a clean and reusable way. They are commonly used for tasks such as logging, input validation, authentication, and caching. They provide a way to add functionality to functions or classes in a modular and reusable manner.