Decorators are useful for modifying functions using other functions. This technique is useful when you need to extend the functionality of a function that you do not want to change.
def decorator(func): def wrap(): print("Extent the original function") func() return wrap def greet(): print("Hello World!") deco = decorator(greet) deco()
if you run it, you get
>>> Extent the original function Hello World!
The construct of a decorator is based on the definition of a function, the decorator in fact, with a function as a single topic. This function will be the one we want to extend with functionality. Inside, a nested function is defined that applies the extensions to add along with the original function. At the end it returns the nested function.
The variable returned, in the deco example, is nothing but the extended function (or better decorated) that we can use from this moment on as deco().
This pattern can be used at any time to wrap any function. In fact Python provides a wrapping mode through the use of a decorator (in fact) that is put before the definition of a function. Decorators are indicated with the @ symbol.
In fact, the following code:
def decoratore(func): def wrap(): print("Extent the original function") func() return wrap @decoratore def greet(): print("Hello World!") greet()
it is a more elegant and correct way to write the previous example. Furthermore, by executing we can see how he greets modified behavior regardless of his definition, obtaining the same result as in the previous example.
A function can have multiple modifiers at the same time.