Skip to content

Decorators

A decorator is a design pattern in Python that allows to add new functionality to an existing object or function without modifying its structure.

Very useful when the same functionality is required in different places, as it is very simple to reuse without having to copy and paste the code. Very easy to maintain.

Measure decorator

The measure decorator is a very simple example of a decorator. It allows to measure the time it takes to execute a function.

src.advanced.decorators.measure

Measure decorator.

This method is a decorator that measures the execution time of a function.

src.advanced.decorators.measure.measure(func)

Measure decorator.

This method is a decorator that measures the execution time in seconds of a function.

Parameters:

Name Type Description Default
func Callable

Function to decorate

required

Returns:

Type Description
func

Decorated function

Source code in src/advanced/decorators/measure.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
def measure(func: Callable):
    """Measure decorator.

    This method is a decorator that measures the execution time in seconds
    of a function.

    Args:
        func (Callable): Function to decorate

    Returns:
        (func): Decorated function
    """

    def wrapper(*args, **kwargs):
        start = time()
        func(*args, **kwargs)
        elapsed_sec = time() - start
        elapsed_format = f"{elapsed_sec:.3f}"
        logger.debug(
            "Method %s executed in %s seconds",
            func.__name__,
            elapsed_format,
        )

    return wrapper

Retry decorator

The retry decorator is a more complex example of a decorator. It allows to retry a function a number of times if it fails.

src.advanced.decorators.retry

Retry decorator.

This method is a decorator that retries a function call a number of times, with a exponential delay between retries.

src.advanced.decorators.retry.retry(attempts=3, delay=1.0)

Retry decorator.

This method is a decorator that retries a function call a number of times, with a exponential delay between retries. If max attempts is reached, the exception is raised by the function, not captured in logs.

Parameters:

Name Type Description Default
attempts int

Number of times to retry the operation.

3
delay float

Delay between retries, in seconds.

1.0

Returns:

Type Description
func

Decorated function

Source code in src/advanced/decorators/retry.py
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
def retry(attempts: int = 3, delay: float = 1.0):
    """Retry decorator.

    This method is a decorator that retries a function call a number of times,
    with a exponential delay between retries.
    If max attempts is reached, the exception is raised by the function,
    not captured in logs.

    Args:
        attempts (int): Number of times to retry the operation.
        delay (float): Delay between retries, in seconds.

    Returns:
        (func): Decorated function
    """

    def decorator(func: Callable):
        def wrapper(*args, **kwargs):
            exception = None
            for current_attempt in range(1, attempts + 1):
                try:
                    logger.debug("Attempt %s", current_attempt)
                    return func(*args, **kwargs)
                except Exception as exc:
                    if current_attempt < attempts:
                        logger.warning("Exception, retrying")
                        sleep((1 + delay) ** current_attempt)
                    else:
                        exception = exc
            logger.error("Raising exception, max attempts reached")
            raise exception

        return wrapper

    return decorator

Singleton decorator

The singleton decorator is a very useful example of a decorator. It allows to ensures that only exists one instance of a class.

src.advanced.decorators.singleton

Singleton decorator.

This method is a decorator to ensures that only exists one instance of a class.

src.advanced.decorators.singleton.singleton(cls)

Singleton decorator.

Method to decorate a class as a singleton. This decorator ensures that exists only one instance of a class.

Parameters:

Name Type Description Default
cls type

Class to decorate

required

Returns:

Type Description
type

Instance of the decorated class

Source code in src/advanced/decorators/singleton.py
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def singleton(cls: type):
    """Singleton decorator.

    Method to decorate a class as a singleton. This decorator ensures that
    exists only one instance of a class.

    Args:
        cls (type): Class to decorate

    Returns:
        (type): Instance of the decorated class
    """

    def __new__singleton(cls: type, *args, **kwargs):  # noqa: ARG001
        if not hasattr(cls, "__singleton"):
            cls.__singleton = object.__new__(cls)
        return cls.__singleton

    cls.__new__ = __new__singleton
    return cls