Learn Python Decorators in this tutorial.
Add functionality to an existing function with decorators. This is called metaprogramming.
A function can take a function as argument (the function to be decorated) and return the same function with or without extension.
Extending functionality is very useful at times, we’ll show real world examples later in this article.
Related course: Complete Python Programming Course & Exercises
Functions are objects
In Python everything is an object, including functions. This means functions can be passed around and returned. When you see it, it may look odd at first:
1 | def hello(): |
Call the methods either message() or hello() and they have the same output. That’s because they refer to the same object.
Now let’s go on with decorators.
Decorators
Example
A decorator takes a function, extends it and returns. Yes, a function can return a function.
1 | def hello(func): |
In the above example, hello() is a decorator.
In the statement1
obj = hello(name)
the function name() is decorated by the function hello().
It wraps the function in the other function.
Example 2
Functions can be extended by wrapping them.
1 | def who(): |
The function who() gets decorated by display().
Syntactic sugar
Decorators are common and can be simplified. While it does exactly the same, its just cleaner code.
Python can simplify the use of decorators with the @ symbol.
1 |
|
This will output exactly the same, but is a cleaner way to write the code.
Stay with me. The call1
2
def name():
is just a simpler way of writing:1
obj = hello(name)
In both cases we apply the decorator to a function.
Arguments
Parameters can be used with decorators. If you have a funtion that prints the sum a + b, like this1
2
3def sumab(a,b):
summed = a + b
print(summed)
You can wrap it in a decorator function.
The example below shows how to do that:
1 | def pretty_sumab(func): |
The function sumab is wrapped by the function pretty_sumab. This is indicated with the @ symbol above it.
Call the function sumab, and see that both the logic of the functions sumab and pretty_sumab are run, with parameters.
Real world examples
Use Case: Time measurement
A decorator can be used to measure how long a function takes to execute.
If you define a simple function that sleeps,1
2def myFunction(n):
time.sleep(n)
You can then measure how long it takes simply by adding the line @measure_time
An example below:
1 | import time |
This will output the time it took to execute the function myFunction(). The cool thing is by adding one line of code @measure_time we can now measure program execution time.
Use Case: Web app
Lets take the use case of web apps. When you build a web app in Flask, you always write url routes.
Every route is a certain page in the web app.
Opening the page /about may call the about_page() method.
1 |
|
In this case it uses the @ symbol for decoration.