Python Decorators that can Take Parameters
What if you want the decorator to be able to take an parameter? Let’s create a “num_times” decorator that when applied will run the wrapped function “n” number of times.
Before we do this, as review (read previous tutorial), we write a basic decorator “num_times” that does not take any parameters. It would look like this …
def num_times(orig_func):
def wrapper(*args, **kwargs):
orig_func(*args, **kwargs)
return wrapper
@num_times
def say_hello(name):
print("Hello " + name)
say_hello("World")
And it would print “Hello World” once.
We would like it to print “Hello” four times when called like this…
@num_times(4)
def say_hello(name):
print("Hello " + name)
say_hello("World")
Since the decorator num_times take a parameter, we need a additional layer of a “decorator generator” nesting like this…
def num_times(n):
def decorator_function(orig_func):
def wrapper(*args, **kwargs):
orig_func(*args, **kwargs)
return wrapper
return decorator_function
The num_times is like a decorator generator. The parameter “n” passed into there is now available for use by the inner functions. We use it in a loop in line 4 below…
def num_times(n):
def decorator_function(orig_func):
def wrapper(*args, **kwargs):
for _ in range(n):
orig_func(*args, **kwargs)
return wrapper
return decorator_function
@num_times(4)
def say_hello(name):
print("Hello " + name)
say_hello("World")
And it prints “Hello World” four times as expected.