python decorators *args and **kwargs

i am trying to fully understand why after having *args and **kwargs as parameters in a wrapper function, i have to also have *args and **kwargs in the original nested function. opposed to being able to use arbitrary parameters to represent *args and **kwargs. my initial line of thinking is that *args and **kwargs will be received as a tuple and a dictionary in the original nested function, so even if the original function doesn’t take in any arguments, an empty tuple and an empty dict would still be passed in. however, if i included *args and **kwargs, they would unpack an empty tuple and dict, which will return nothing, leading to no error being thrown. i want to find out if my assumption is correct

def decorator_function(original_function):
    def wrapper_function(*args,**kwargs):
        print('this print statement is the added functionality of this decorator function')
        original_function(args,kwargs) 

    return wrapper_function 

@decorator_function
def display():
    print('display ran')

@decorator_function 
def display_info(name,age): 
    print(f"display function ran with {name, age}")

display_info('foo',100)
display()

def decorator_function(original_function):
    def wrapper_function(*args,**kwargs):
        print('this print statement is the added functionality of this decorator function')
        original_function(*args,**kwargs) 

    return wrapper_function 

@decorator_function
def display():
    print('display ran')

@decorator_function 
def display_info(name,age): 
    print(f"display function ran with {name} and {age}")

display_info('foo',100)
display()

>Solution :

* and ** in method signature works exactly opposite to how it works when calling the method – *args turns multiple arguments into a single list named args. Same with **kwargs, but making a dictionary instead.

So in your first example, if you don’t pass any arguments, you are trying to call original_function like this: original_function([], {}). So obviously, as original function is display() that does not accept any arguments, you get an error.

Now, if you instead call it starred as original_function(*args,**kwargs), both of those get unpacked into nothing. As in, as both are empty collection, you are making a original_function() call.

Leave a Reply