How to use a Python decorator?

Home » Python » How to use a Python decorator?

Table of Contents

Introduction to a Python decorator

Python decorator is a design pattern that allows you to add or modify functionality to functions or methods without changing their actual code. Decorators are functions that take another function as an argument and extend or alter its behavior, returning a new function with the enhanced functionality.

Decorators are commonly used in Python to:

  • Add functionality to functions or methods.
  • Modify or extend the behavior of a function in a reusable and readable way.
  • Apply cross-cutting concerns like logging, access control, or memoization.

How Python Decorators Work

A decorator is essentially a function that takes another function (or method) as an argument and returns a new function. The original function gets passed to the decorator and is typically called inside the decorator function, either before or after modifying it.

Basic Syntax of a Python Decorator:


def decorator_function(original_function):
    def wrapper_function():
        print("Wrapper executed this before {}".format(original_function.__name__))
        return original_function()
    return wrapper_function

@decorator_function
def display():
    print("Display function executed!")

display()

Explanation:

  1. decorator_function is a decorator that takes original_function as an argument.
  2. wrapper_function is the inner function that modifies the behavior of original_function. It adds additional functionality (e.g., printing a message before executing the original function).
  3. The @decorator_function syntax is a shorthand for applying the decorator to the function display().
  4. When display() is called, it actually calls the wrapper_function inside the decorator, which first prints the added message and then calls display().

Explanation of Components:

  1. Original Function: This is the function that you want to decorate (in this case, display()).
  2. Wrapper Function: This is a new function that wraps the original function. It can perform actions before, after, or around the original function call.
  3. Return: The decorator returns the wrapper_function, which becomes the new version of the original function.

Common Use Cases for Decorators:

  1. Logging: Adding logging functionality to functions.
  2. Access Control: Checking permissions or access before allowing a function to run.
  3. Caching / Memoization: Storing the results of expensive function calls and returning the cached result when the same inputs occur again.
  4. Timing: Measuring how long a function takes to execute.

Example of a Logging Decorator:


def log_decorator(function):
    def wrapper():
        print(f"Function {function.__name__} is being called.")
        return function()
    return wrapper

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

say_hello()

Decorators with Arguments

If the function you’re decorating has parameters, the decorator must be able to handle them. You can achieve this by using *args and **kwargs to pass any number of arguments to the original function.

Example


def decorator_with_args(func):
    def wrapper(*args, **kwargs):
        print(f"Arguments were: {args} and {kwargs}")
        return func(*args, **kwargs)
    return wrapper

@decorator_with_args
def add(a, b):
    return a + b

result = add(3, 5)
print(result)

Chaining Multiple Decorators

You can apply multiple decorators to a single function by stacking them on top of each other. Each decorator wraps the function, and they are applied in a bottom-to-top order.


def decorator1(func):
    def wrapper():
        print("Decorator 1")
        return func()
    return wrapper

def decorator2(func):
    def wrapper():
        print("Decorator 2")
        return func()
    return wrapper

@decorator1
@decorator2
def hello():
    print("Hello!")

hello()

Conclusion of Python decorator

Python decorators are a powerful feature in Python that allows you to modify or extend the behavior of functions or methods in a reusable way.

They are commonly used in a variety of scenarios like logging, authorization checks, caching, and more.

Decorators can be written to handle functions with arguments and can be stacked to apply multiple modifications to a single function.

By using decorators, you can make your code cleaner, more modular, and reusable while maintaining the separation of concerns.


Posted

in

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *