Chapter 2: Python decorators

Decorating functions with parameters

face Josiah Wang

Can we decorate a function that has some parameters?

Of course we can. Just include the parameters in the inner (wrapper) function.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
def validator(func):
    def wrapper(numerator, denominator):
        try:
            return func(numerator, denominator)
        except ZeroDivisionError:
            print("Sorry, I do not know how to divide by 0.")
            return float("NaN")

    return wrapper

@validator
def divide(numerator, denominator):
    return numerator/denominator

answer = divide(5, 0) # Sorry, I do not know how to divide by 0.
print(answer) # nan

What if you don’t need to know what parameters are involved? Just use *args and **kwargs in the inner function, and pass them onto the function you are wrapping.

def repeat(func):
    def wrapper(*args, **kwargs):
        func(*args, **kwargs)
        func(*args, **kwargs)
    return wrapper

@repeat
def greet(message, firstname, lastname):
    print(f"{message}, {firstname} {lastname}!")

greet("Merry Christmas", "Josiah", "Wang")

If you run the code, you should get

Merry Christmas, Josiah Wang!
Merry Christmas, Josiah Wang!