Python Decorators are the most powerful functionality which can keep tack on the existing class or function and which can also extend the behavior of a callable without permanently modifying.
Any sufficient generic functionality you can tack on to an existing class or function’s behavior can make a great use case for decoration.
Take an example, Suppose you have 45 Functions with business logic in your report generating Code.
Your Senior Technical Lead asks you to add input/output logging to each step in the report generator and wants you to submit it in 2 days. ABC Comp needs it for auditing purposes.
You might be facing hard times to modify each of those 45 functions and clutter them up with manual logging calls which is actually tough.
Decorators can save your life! but they require a very solid grasp of several advanced concepts in Python, including the properties of first-class functions.
Before jumping in, let’s recollect the concepts of Python Functions.
Functions are objects which can be assigned to variables and can be passed to and returned from other functions and functions can be defined inside other functions.
Decorators allow you to define reusable building blocks that can change or extend the behavior of other functions, in simple words, A decorator is a callable that takes a callable as input and returns another callable.
Here, the null_decorator is a callable function that takes another callable as its input, and it also returns the same input callable without actually modifying it.
In this example, I’ve defined a yes function and then immediately decorated it by running it through the null_decorator function.
Putting an @null_decorator line in front of the function definition is the same as defining the function first and then running through the decorator. Using the @ syntax is just syntactic sugar and a shortcut for this commonly used pattern.
Instead of simply returning the input function as the null decorator did, this lowercase decorator defines a new function and uses it to wrap the input function in order to modify its behavior at call time.
Time to see the Lowercase decorator in action
So, the Decorators modify the behavior of a callable through a wrapper closure so you don’t have to force it to permanently modify the original function.