I am trying to understand decorators. I want to define a decorator that can handle any arbitrary argument. I am trying the following:
def a_decorator_passing_arbitrary_arguments(function_to_decorate):
def a_wrapper_accepting_arbitrary_arguments(*args,**kwargs):
print('The positional arguments are', args)
print('The keyword arguments are', kwargs)
function_to_decorate(*args)
return a_wrapper_accepting_arbitrary_arguments
This is based on this tutorial and it supposedly handles any type of argument. However when I pass only keyword arguments I get the following output with function f(a,b,c)
:
@a_decorator_passing_arbitrary_arguments
def f(a,b,c):
print("The arguments here are the following: {0}, {1}, {2}.".format(a,b,c))
f(a='ali', b='emma', c='t')
The output:
The positional arguments are ()
The keyword arguments are {'a': 'ali', 'b': 'emma', 'c': 't'}
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-cc5ee8d7120a> in <module>
----> 1 f(a='ali', b='emma', c='t')
<ipython-input-1-af03800e2abd> in a_wrapper_accepting_arbitrary_arguments(*args, **kwargs)
3 print('The positional arguments are', args)
4 print('The keyword arguments are', kwargs)
----> 5 function_to_decorate(*args)
6 return a_wrapper_accepting_arbitrary_arguments
TypeError: f() missing 3 required positional arguments: 'a', 'b', and 'c'
How can I avoid getting this error in the case when all the variables are passed as keyword arguments?
CodePudding user response:
You are currently only passing on the positional arguments, not the keyword arguments as well, to the wrapped function.
def a_decorator_passing_arbitrary_arguments(function_to_decorate):
def a_wrapper_accepting_arbitrary_arguments(*args,**kwargs):
print('The positional arguments are', args)
print('The keyword arguments are', kwargs)
# function_to_decorate(*args) # Wrong
return function_to_decorate(*args, **kwargs) # Right
return a_wrapper_accepting_arbitrary_arguments
(You should also return whatever function_to_decorate
returns from the wrapper.)