A decorator is a feature in python that allows you to add extra capabilities to your function, without having to change the inner workings of your function.
Some examples of uses of decorators include: determining the execution time of a function, determine which URL call should result in this function being called, adding logging messages when a function starts/stops. There are many uses for this.
More technically, a decorator is a function that takes another function as an argument, adds some functionality then returns another function. This happens without altering the original source code of the function that was passed.
So the above should explain the power of decorators. So how does it actually work? Well it’s a combination of a few interesting features in python:
Functions are First-Class Objects: this means you can assign functions to variables, pass them as arguments, and return them as values from other functions.
Scope / Closure: this specifically refers to how a nested function that has access to variable(s) from its enclosing function.
It’s these two things that make it possible to have decorators. This is a diagram that shows what happens conceptually. The actual call to the original function is circumvented to call the decorator which encapsulates the call to the original call with some additional functionality. That’s where the magic lies
To find out more about decorators including a practical example using parameters, you can see our full article Simple Guide To Decorators in Python 3 – When and How to Use Them. The articles show examples with code you can readily cut and paste.