Python Programming/Decorators

Duplicated code is recognized as bad practice in software for lots of reasons, not least of which is that it requires more work to maintain. If you have the same algorithm operating twice on different pieces of data you can put the algorithm in a function and pass in the data to avoid having to duplicate the code. However, sometimes you find cases where the code itself changes, but two or more places still have significant chunks of duplicated boilerplate code. A typical example might be logging:

In a case like this, it's not obvious how to factor out the duplication. We can follow our earlier pattern of moving the common code to a function, but calling the function with different data is not enough to produce the different behavior we want (add or multiply). Instead, we have to pass a function to the common function. This involves a function that operates on a function, known as a higher-order function.

Decorator in Python is a syntax sugar for high-level function.

Minimal example of property decorator:

The above example is really just a syntax sugar for codes like this:

Minimal Example of generic decorator:

A good use for the decorators is to allow you to refactor your code so that common features can be moved into decorators. Consider for example, that you would like to trace all calls to some functions and print out the values of all the parameters of the functions for each invocation. Now you can implement this in a decorator as follows:

Then you can use the decorator on any function that you defined by:

On running this code you would see output like

Alternately, instead of creating the decorator as a class, you could have used a function as well. Remember it is good practice to return the function or a sensible decorated replacement for the function so that decorators can be chained.