Timing Functions With Decorators - Python
Last Updated :
05 Apr, 2021
Everything in Python is an object. Functions in Python also object. Hence, like any other object they can be referenced by variables, stored in data structures like dictionary or list, passed as an argument to another function, and returned as a value from another function. In this article, we are going to see the timing function with decorators.
Decorator: A decorator is used to supercharge or modify a function. A decorator is a higher-order function that wraps another function and enhances it or changes it.
Example :
The best way to explain what it is by coding our own decorator. Suppose, you want to print * 10 times before and after the output of some function. It would be very inconvenient to use print statements in every function again and again. We can do this efficiently with the help of a decorator.
Code:
Python3
def my_decorator(func):
def wrapper_function(*args, **kwargs):
print("*"*10)
func(*args, **kwargs)
print("*"*10)
return wrapper_function
def say_hello():
print("Hello Geeks!")
@my_decorator
def say_bye():
print("Bye Geeks!")
say_hello = my_decorator(say_hello)
say_hello()
say_bye()
Output:
**********
Hello Geeks!
**********
**********
Bye Geeks!
**********
Explanation :
In the above example, my_decorator is a decorator function, which accepts func, a function object as an argument. It defines a wrapper_function which calls func and executes the code that it contains as well. The my_decorator function returns this wrapper_function.
So, what happens when we write @my_decorator before defining any function? Consider the example of the say_hello function above which is not decorated by any decorator at the time of definition. We can still use our decorator for decorating its output by calling the my_decorator function and passing the say_hello function object as a parameter, which will return a wrapper_function with two print statements, calling the say_hello() function in between. If we receive this modified function in the say_hello object itself, whenever we call say_hello() we'll get the modified output.
Instead of writing this complex syntax, we can simply write @my_decorator before defining the function and leave the rest of the work for python interpreter as shown in the case of say_bye function.
Timer Function using Decorator
The timer function is one of the applications of decorators. In the below example, we have made a timer_func function that accepts a function object func. Inside the timer function, we have defined wrap_func which can take any number of arguments (*args) and any number of keyword arguments (**kwargs) passed to it. We did this to make our timer_func more flexible.
In the body of wrap_func, we recorded the current time t1 using the time method of the time module, then we have called the function func passing the same parameters (*args, **kwargs) that were received by wrap_func and stored the returned value in the result. Now we have again recorded the current time t2 and printed the difference between the recorded times i.e. { t2 - t1 } with precision up to the 4th decimal place. This {t2 - t1} is the time passed during the execution of the function func. At last, we have returned the result value inside wrap_func function and returned this wrap_func function inside timer_func function.
We have also defined the long_time function using @timer_func decorator, so whenever we call long_time function it will be called like :
timer_func(long_time)(5)
The timer_func function when called passing long_time as a parameter returns a wrap_func function and a function object func starts pointing to the long_time function.
wrap_func(5)
Now the wrap_func will execute as explained above and the result is returned.
Python3
from time import time
def timer_func(func):
# This function shows the execution time of
# the function object passed
def wrap_func(*args, **kwargs):
t1 = time()
result = func(*args, **kwargs)
t2 = time()
print(f'Function {func.__name__!r} executed in {(t2-t1):.4f}s')
return result
return wrap_func
@timer_func
def long_time(n):
for i in range(n):
for j in range(100000):
i*j
long_time(5)
Output:
Function 'long_time' executed in 0.0219s
Similar Reads
How to use Function Decorators in Python ?
In Python, a function can be passed as a parameter to another function (a function can also return another function). we can define a function inside another function. In this article, you will learn How to use Function Decorators in Python. Passing Function as ParametersIn Python, you can pass a fu
3 min read
Memoization using decorators in Python
Recursion is a programming technique where a function calls itself repeatedly till a termination condition is met. Some of the examples where recursion is used are a calculation of fibonacci series, factorial, etc. But the issue with them is that in the recursion tree, there can be chances that the
3 min read
Decorators with parameters in Python
Prerequisite: Decorators in Python, Function DecoratorsWe know Decorators are a very powerful and useful tool in Python since it allow programmers to modify the behavior of functions or classes. In this article, we will learn about the Decorators with Parameters with the help of multiple examples. P
4 min read
Decorators in Python
In Python, decorators are a powerful and flexible way to modify or extend the behavior of functions or methods, without changing their actual code. A decorator is essentially a function that takes another function as an argument and returns a new function with enhanced functionality. Decorators are
10 min read
Timeit in Python with Examples
The timeit module in Python accurately measures the execution time of small code snippets, offering more consistent results than time.time() by avoiding background interference and disabling garbage collection. Itâs ideal for comparing code performance, benchmarking and optimization and can be used
3 min read
Python | datetime.timedelta() function
Python timedelta() function is present under datetime library which is generally used for calculating differences in dates and also can be used for date manipulations in Python. It is one of the easiest ways to perform date manipulations. Syntax : datetime.timedelta(days=0, seconds=0, microseconds=0
4 min read
Attaching a Decorator to All Functions within a Class in Python
Decorators in Python allow us to add extra features to functions or methods of class without changing their code. Sometimes, we might want to apply a decorator to all methods in a class to ensure they all behave in a certain way. This article will explain how to do this step by step.Applying Decorat
2 min read
Nested Decorators in Python
Everything in Python is an object. Even function is a type of object in Python. Decorators are a special type of function which return a wrapper function. They are considered very powerful in Python and are used to modify the behaviour of a function temporarily without changing its actual value. Nes
2 min read
Why does Python code run faster in a function?
Python, renowned for its simplicity and readability, has some interesting performance characteristics that might not be immediately obvious to beginners. One such characteristic is that code often runs faster when it's inside a function. This behavior can be puzzling at first, but it becomes clear w
4 min read
Decorator to print Function call details in Python
Decorators in Python are the design pattern that allows the users to add new functionalities to an existing object without the need to modify its structure. Decorators are generally called before defining a function the user wants to decorate. Example: Python3 # defining a decorator def hello_decora
3 min read