Decorators in Python

Decorator is a design pattern to extend the functionality of a function without modifying the structure of the original function. Decorators are usually applied to functions using the @decorator syntax, immediately before the function definition.

Example of how to use a decorator to extend the functionality of a function:

 1def my_decorator(func):
 2    def wrapper(*args, **kwargs):
 3        # Do something before the function is called
 4        result = func(*args, **kwargs)
 5        # Do something after the function is called
 6        return result
 7    return wrapper
 8
 9@my_decorator
10def add(x, y):
11    return x + y

The add function is decorated with the my_decorator function. When the add function is called, the code in the wrapper function will be executed before and after the call to add. This allows the my_decorator function to extend the functionality of the add function without modifying the structure of the add function itself.

Example of a decorator function that calculates the execution time of a function:

 1import time
 2
 3def execution_time(func):
 4    def wrapper(*args, **kwargs):
 5        start = time.time()
 6        result = func(*args, **kwargs)
 7        end = time.time()
 8        print(f'{func.__name__} took {end - start} seconds to execute.')
 9        return result
10    return wrapper
11
12@execution_time
13def some_function():
14    time.sleep(2)
15
16some_function() # prints "some_function took 2.00 seconds to execute."

Some common decorators that are used in Django:

  1. @login_required: This decorator is used to require a user to be logged in to access a view. If a user is not logged in, they will be redirected to the login page.
  2. @permission_required: This decorator is used to require a user to have a specific permission in order to access a view. If a user does not have the required permission, they will be redirected to the login page.
  3. @csrf_exempt: This decorator is used to exempt a view from Django's built-in Cross-Site Request Forgery (CSRF) protection. This can be useful if you want to allow requests to be made to a view without requiring a CSRF token.
  4. @cache_page: This decorator is used to cache the results of a view, so that subsequent requests for the same view can be served from the cache instead of being generated by the view. This can improve the performance of your application.

Use cases of decorators

There are several reasons why you might want to use decorators in your Python code:

  1. Decorators can be used to extend the functionality of a function without modifying the structure of the original function. This allows you to keep your code clean and organized, and avoid duplication of code.
  2. Decorators can be used to add additional functionality to a function without changing the code inside the function. This can be useful for tasks such as logging, validating arguments, or measuring execution time.
  3. Decorators can be used to change the behavior of a function at runtime. This can be useful for tasks such as caching the results of a function, or retrying a function if it fails.
  4. Decorators can be applied to multiple functions, allowing you to reuse the same code for multiple functions. This can save you time and make your code more maintainable.

Author: Sadman Kabir Soumik