Course Content
Mastering Python: Closures and Decorators
Mastering Python: Closures and Decorators
Flexible Decorators
Different functions require a varying number of arguments.
To create a decorator that can be applied to functions with varying numbers of arguments, you can use the *args
and **kwargs
as arguments in the wrapper()
function.
Let's create an indicate decorator that prints information about the function execution:
- Print a message that the function has started execution.
- Print the arguments taken by the function.
- Call the function and save the result that is returned by the function.
- Print a message that the function has finished execution.
- Return the result.
def indicate(func): def wrapper(*args, **kwargs): print("=" * 5,"Func execution starts:", func) print("Taken arguments:", *args, kwargs) result = func(*args, **kwargs) print("=" * 5, "Func execution ends:", func) return result return wrapper @indicate def add_two(a, b): return a + b @indicate def add_three(a, b, c): return a + b + c @indicate def add_many_kwargs(**kwargs): string = "" number = 0 for key, value in kwargs.items(): string += key number += value return (string, number) print("Returned:", add_two(14, 21), "\n") print("Returned:", add_three(225, 12, 11), "\n") print("Returned:", add_many_kwargs(first=51, second=11, third=47, fourth=93))
The indicate()
has the wrapper()
that takes the *args
and **kwargs
. That means that wrapper()
can take every number of arguments and keyword arguments.
The add_two()
function takes 2 arguments.
The add_three()
function takes 3 arguments.
The add_many_kwargs()
takes a different number of keyword arguments.
The indicate()
decorator can be used for every function.
So, the *args
and **kwargs
in the wrapper()
allow us to use the decorator for any function.
Note
Remember to unpack the received
args
andkwargs
using asterisks (*
for args and**
forkwargs
) when passing them to a nested function.
If you don't understand or have forgotten how to do this, feel free to come back here.
Thanks for your feedback!