In this tutorial we want to learn about Function Decorators in Python, first of all let’s talk about function decorators.
What is Function Decorators in Python?
Function decorators are powerful functions for modifying and enhancing the behavior of functions. using decorators you can add functionality to a function without changing its source code. You can use decorators for different purposes, for example from logging to memorization to performance profiling. you can create decorators in different ways.
First Way for Creating Function Decorators
The first way of creating decorators is to use randomization. for example you want to create a decorator that randomly modifies the output of a function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import random def random_decorator(func): def wrapper(*args, **kwargs): result = func(*args, **kwargs) if random.randint(0, 1) == 0: return result.upper() else: return result.lower() return wrapper @random_decorator def greet(name): return f"Hello {name}" print(greet("Codeloop")) print(greet("Parwiz")) |
In this example random_decorator randomly converts the output of the greet function to uppercase or lowercase.
This will be the result
Second Way for Creating Function Decorators
Another way for creating Python decorators is to use external APIs or services. for example, you want to create a decorator that adds random image or quote to the output of functions by calling an external API.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import requests def random_image_decorator(func): def wrapper(*args, **kwargs): result = func(*args, **kwargs) response = requests.get("https://api.unsplash.com/photos/random", params={"orientation": "landscape", "client_id": "<UNSPLASH_CLIENT_ID>"}) if response.ok: image_url = response.json()["urls"]["regular"] return f"{result}\n{image_url}" else: return result return wrapper @random_image_decorator def greet(name): return f"Hello {name}" print(greet("GeeksCoders")) print(greet("John")) |
In this example random_image_decorator calls Unsplash API to retrieve random landscape image and adds it to the output of the greet function.
More Examples on Function Decorators
Now let’s create some more examples about this concept in Python
Example 1: Logging Decorator
A common use of decorators is to log the function calls and their arguments.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
def logging_decorator(func): def wrapper(*args, **kwargs): print(f"Calling function '{func.__name__}' with arguments {args} and {kwargs}") result = func(*args, **kwargs) print(f"'{func.__name__}' returned {result}") return result return wrapper @logging_decorator def add(a, b): return a + b print(add(5, 3)) print(add(a=10, b=20)) |
Example 2: Timing Decorator
You can create a decorator to measure the execution time of a function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import time def timing_decorator(func): def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) end_time = time.time() print(f"Function '{func.__name__}' took {end_time - start_time:.4f} seconds to execute") return result return wrapper @timing_decorator def slow_function(): time.sleep(2) return "Finished" print(slow_function()) |
Example 3: Caching (Memoization) Decorator
You can create a decorator to cache the results of expensive function calls.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
def cache_decorator(func): cache = {} def wrapper(*args): if args in cache: return cache[args] result = func(*args) cache[args] = result return result return wrapper @cache_decorator def fibonacci(n): if n in (0, 1): return n return fibonacci(n - 1) + fibonacci(n - 2) print(fibonacci(10)) print(fibonacci(20)) print(fibonacci(30)) |
So we can say that Function decorators in Python are powerful for extending the functionality of functions without modifying their source code.
Subscribe and Get Free Video Courses & Articles in your Email