Decorators in Python

In Python, a decorator is a function that takes another function as input and returns a new function that usually extends or modifies the behavior of the input function without changing its source code. Decorators are a powerful feature of Python that allows you to add extra functionality to existing functions or classes, without modifying their source code.

Here’s an example of a simple decorator:

python
def my_decorator(func):
    def wrapper():
        print("Before the function is called.")
        func()
        print("After the function is called.")
    return wrapper

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

# Call the decorated function
say_hello()

In this example, we define a decorator called `my_decorator`, which takes a function `func` as input and returns a new function called `wrapper`. The `wrapper` function adds some extra behavior before and after the original function is called. We then apply the decorator to a function called `say_hello` using the `@` syntax. When we call `say_hello()`, the decorator is applied automatically, and the output will be:

Before the function is called.
Hello!
After the function is called.

Note that when we apply the decorator to the function using the `@` syntax, we are effectively reassigning the name `say_hello` to the new decorated function (`wrapper` in this case).

You can also define decorators that take arguments:

python
def repeat(num):
    def my_decorator(func):
        def wrapper():
            for i in range(num):
                func()
        return wrapper
    return my_decorator

@repeat(num=3)
def say_hello():
    print("Hello!")

# Call the decorated function
say_hello()

In this example, we define a decorator called `repeat`, which takes an argument `num`. The decorator itself returns another decorator called `my_decorator`, which takes a function `func` as input and returns a new function called `wrapper`. The `wrapper` function repeats the original function `num` times. We then apply the `repeat` decorator to a function called `say_hello` using the `@` syntax, passing in the argument `num=3`. When we call `say_hello()`, the decorator is applied automatically, and the output will be:

Hello!
Hello!
Hello!

This is just a basic overview of decorators in Python. Decorators can be used in many different ways, and there are many advanced techniques for creating and using them.