Python decorators allow modifying the behavior of functions and classes, without changing their code. Let’s start from a simple example and see where a decorator would fit.
Here is a simple function to play with:
Let’s assume we want to add a logging mechanism for functions like myfunc that adds a print before the function is called. We can use a wrapper function that prints before calling the function, which is straightforward in Python since functions are first-class objects and can be passed to other functions:
Essentially, we are replacing myfunc with another function that has more functionality. To make this process simpler, Python provides the decorator syntax for these cases:
The @print_wrapper decorator adds the wrapper for the myfunc2 function without explicit calls to print_wrapper as we did for myfunc.
Bodo provides the jit decorator that replaces data analytics functions (e.g. using Pandas) with an optimized and parallelized binary version automatically through just in time (JIT) compilation. This is as if the function is rewritten to parallel C++ by an expert, but happens transparently in real-time. For example:
In this case, CPUDispatcher is the name of the wrapper that manages compilation and calls to the optimized version of my_pandas_func.