9 Python Decorator Exercises and Examples


In Python, a decorator allows us to wrap another function in order to extend the behavior of the wrapped function, without permanently modifying it. Decorators provide a simple syntax for calling higher-order functions.

In this post, I will provide some exercises and examples that illustrate the usage of decorators in Python. Let’s dive right in.

1. Basic decorator

def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

def say_hello():
    print("Hello!")

say_hello = my_decorator(say_hello)

say_hello()

Output:

2. Using the @ symbol for decorators

def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()

Output:

3. Decorating functions with arguments

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Something is happening before the function is called.")
        func(*args, **kwargs)
        print("Something is happening after the function is called.")
    return wrapper

@my_decorator
def greet(name):
    print(f"Hello {name}!")

greet("Pythonista Planet")

Output:

4. Returning values from decorated functions

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Something is happening before the function is called.")
        result = func(*args, **kwargs)
        print("Something is happening after the function is called.")
        return result
    return wrapper

@my_decorator
def add(x, y):
    return x + y

result = add(5, 10)
print(result)

Output:

5. Using multiple decorators on a single function

def decorator_1(func):
    def wrapper():
        print("Decorator 1")
        func()
    return wrapper

def decorator_2(func):
    def wrapper():
        print("Decorator 2")
        func()
    return wrapper

@decorator_1
@decorator_2
def greet():
    print("Hello!")

greet()

Output:

6. Class decorators

class MyDecorator:
    def __init__(self, func):
        self.func = func

    def __call__(self):
        print("Something is happening before the function is called.")
        self.func()
        print("Something is happening after the function is called.")

@MyDecorator
def greet():
    print("Hello!")

greet()

Output:

7. Decorators with arguments

def repeat(num_times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(num_times):
                func(*args, **kwargs)
        return wrapper
    return decorator

@repeat(3)
def greet(name):
    print(f"Hello {name}")

greet("Pythonista Planet")

Output:

8. Caching return values

import functools

@functools.lru_cache(maxsize=4)
def fibonacci(num):
    print(f"Calculating fibonacci({num})")
    if num < 2:
        return num
    return fibonacci(num - 1) + fibonacci(num - 2)

print(fibonacci(10))

Output:

9. Making a decorator with user-defined exception

def validate(func):
    def wrapper(*args):
        if len(args) > 0 and isinstance(args[0], int):
            if args[0] > 0:
                return func(*args)
        raise ValueError("Value must be a positive integer")
    return wrapper

@validate
def print_num(num):
    print(num)

print_num(10)
print_num(-1)

Output:

I hope that these examples would give you a good understanding of decorators in Python. Decorators can be a powerful tool, and while they might seem a bit confusing at first, with some practice, you’ll be able to use them effectively in your code.

Remember that they are simply functions that take a function and return a new function. This concept of functions returning functions is one of the cornerstones of functional programming and is part of what makes Python such a powerful and flexible language.

If you found this post useful, check out my post on 20 Python File I/O Exercises and Examples.

Ashwin Joy

I'm the face behind Pythonista Planet. I learned my first programming language back in 2015. Ever since then, I've been learning programming and immersing myself in technology. On this site, I share everything that I've learned about computer programming.

Leave a Reply

Your email address will not be published. Required fields are marked *

Recent Posts