What are decorators in Python? Why are they useful?
Let's say I'm building a Python project and I want to know how long it takes for each of my functions to run. I could build timing functionality within each of my functions but what if I have hundreds of functions? That would take far too long.
Instead I'm going to create a function to do it for me. Let's call it timer
and give it another function as an argument. Inside, we'll define a function called wrapper
. Next let's define a variable that stores the start time. And finally we'll run the function that's passed into timer
.
After the function has executed we can determine how long it took by taking the current time and subtracting the starting time from it. Next we can print that it took t2-t1 seconds to execute. Finally let's return the wrapper function.
import time
def timer(func):
def wrapper():
t1 = time.time()
func()
t2 = time.time() - t1
print(f'{func.__name__} ran in {t2} seconds')
return wrapper
@timer
def execute_this():
time.sleep(1.3)
@timer
def execute_that():
time.sleep(.4)
execute_this()
execute_that()
Now finally on the to decorator!
Let's put @timer
above each of the functions we want to time. Python sees this @
symbol and understands the following function needs to be passed into a function named after the @ symbol, in this case timer
.
The function execute_this
runs in timer
with the t1 and t2 variables determining the run time of each function. As you can see, reusing the timer
function as a decorator allows us to save time and code as we expand our project and add many more functions that need to be timed.
Top comments (0)