Home Python C Language C ++ HTML 5 CSS Javascript Java Kotlin SQL DJango Bootstrap React.js R C# PHP ASP.Net Numpy Dart Pandas Digital Marketing

What are Decorators in Python?


In Python, a decorator is a function that allows you to modify the behavior of another function or method. Decorators are commonly used to enhance the functionality of functions or methods without changing their code. They provide a simple and readable way to extend the functionality of functions in a modular way.

Understanding the Basics of Decorators

At its core, a decorator is a function that takes another function as an argument, adds some functionality, and then returns a new function that behaves in the same way as the original function but with added behavior.

Decorator Syntax

The syntax for a decorator is very simple. Here's an example of how you would use a decorator in Python:

    def my_decorator(func):
        def wrapper():
            print("Something is happening before the function is called.")
            func()
            print("Something is happening after the function is called.")
        return wrapper

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

    say_hello()
        

In this example, the my_decorator function takes func as an argument (the function to be decorated). Inside the decorator, we define a nested function called wrapper, which adds functionality before and after calling the original function (func). The @my_decorator syntax is shorthand for passing the say_hello function to my_decorator as an argument.

Output of the Example:

    Something is happening before the function is called.
    Hello!
    Something is happening after the function is called.
        

Why Use Decorators?

Decorators are useful for several reasons:

Real-World Example: Logging Decorator

One common use case for decorators is logging. You can create a decorator that logs the time when a function is called and when it finishes execution. Here's an example:

    import time

    def log_function_call(func):
        def wrapper():
            print(f"Function {func.__name__} called at {time.ctime()}")
            func()
            print(f"Function {func.__name__} finished at {time.ctime()}")
        return wrapper

    @log_function_call
    def process_data():
        print("Processing data...")
        time.sleep(2)
        print("Data processed.")

    process_data()
        

In this example, the log_function_call decorator logs the time when the process_data function is called and when it finishes. The time.sleep(2) is used to simulate a time-consuming process.

Output of the Example:

    Function process_data called at Fri Nov 30 10:30:02 2024
    Processing data...
    Data processed.
    Function process_data finished at Fri Nov 30 10:30:04 2024
        

Decorators with Arguments

Decorators can also accept arguments. This allows you to create more flexible decorators that can be customized based on input. Here's an example of a decorator that accepts an argument:

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

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

    greet()
        

In this example, the repeat decorator takes an argument num_times, which specifies how many times the decorated function should be called. The greet function is called three times because of the decorator.

Output of the Example:

    Hello!
    Hello!
    Hello!
        

Chaining Multiple Decorators

You can apply multiple decorators to a single function by stacking them. The decorators are applied from bottom to top:

    def decorator_one(func):
        def wrapper():
            print("Decorator One")
            func()
        return wrapper

    def decorator_two(func):
        def wrapper():
            print("Decorator Two")
            func()
        return wrapper

    @decorator_one
    @decorator_two
    def greet():
        print("Hello!")

    greet()
        

In this example, greet is decorated with both decorator_one and decorator_two. The output shows the decorators are applied in the order from bottom to top.

Output of the Example:

    Decorator One
    Decorator Two
    Hello!
        

Class-based Decorators

Decorators in Python are not limited to functions; they can also be used with classes. A class-based decorator works similarly to a function-based decorator but is implemented using a class. Here's an example:

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

        def __call__(self):
            print("Before function call")
            self.func()
            print("After function call")

    @DecoratorClass
    def greet():
        print("Hello!")

    greet()
        

In this example, the DecoratorClass acts as a decorator. The __call__ method allows the instance of the class to be used as a decorator, adding functionality before and after the function call.

Output of the Example:

    Before function call
    Hello!
    After function call
        

Conclusion

Decorators are a powerful feature in Python that allows you to modify or enhance the behavior of functions or methods in a clean and modular way. By using decorators, you can add functionality such as logging, access control, and caching without modifying the original function. They are widely used in Python frameworks and libraries to simplify code and increase reusability.



Advertisement





Q3 Schools : India


Online Complier

HTML 5

Python

java

C++

C

JavaScript

Website Development

HTML

CSS

JavaScript

Python

SQL

Campus Learning

C

C#

java