I'm learning about Python decorators and I have some difficulties understanding how passing arguments to the decorated function works. I'm not talking about passing arguments to the decorator itself but of the case where the original function takes additional arguments. For instance, I'm trying to understand the following simple example (credits for the code snippet goes to this answer):
def decorator(fn):
def wrapper(arg1, arg2):
print("I got args! Look: {0}, {1}".format(arg1, arg2))
fn(arg1, arg2)
return wrapper
@decorator
def print_full_name(first_name, last_name):
print("My name is {0} {1}".format(first_name, last_name))
print_full_name("John", "Doe")
# outputs:
# I got args! Look: John Doe
# My name is John Doe
So, if I intentionally break the code by removing the arguments arg1
and arg2
of the wrapper, I get the following error: TypeError: wrapper() takes 0 positional arguments but 2 were given
. It's strange to me that the wrapper is expecting 2 arguments when it's defined without any arguments inside the parentheses. Also, is it unclear to me how the first_name
and last_name
argument values are "mapped" to the arguments of the wrapper function. We only pass those arguments to the print_full_name
function but it seems they also get passed to the wrapper
function. Maybe this has to do with the order in which things are run but this is not clear for me.
I know they are a lot of great answers here regarding this topic but I could not find one that clearly explains this specific part. Any help would be greatly appreciated.