In Python, a decorator is a function that takes another function as input and extends or modifies the behavior of the input function without changing its source code. Decorators allow you to add functionality to a function or class at runtime, without having to modify the original code.

        In other words, a decorator in Python is a way to modify or enhance the behavior of a function or class by wrapping it with another function. This can be useful in a variety of situations, such as:

  1. Adding authentication or logging to a function
  2. Timing the execution of a function
  3. Caching the results of a function
  4. Adding error handling to a function

Here's an example of a simple decorator in Python:
def my_decorator(func):
    def wrapper():
        print("Before function is called")
        func()
        print("After function is called")
    return wrapper

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

say_hello()

        In this example, my_decorator is a function that takes another function as input and returns a new function that wraps the original function. The wrapper function adds some extra functionality before and after the original function is called. The @my_decorator syntax is a shorthand way of applying the decorator to the say_hello function.

When say_hello() is called, the output will be:
Before function is called
Hello World
After function is called

        As you can see, the output of the say_hello function has been modified by the decorator.