I'm applying a decorator to some functions, and the decorator would require some arguments in the functions. Yet, I would assign some default values to the arguments. The decorator receives the arguments with *args, **kwargs
.
def decorator(fn):
def wrapper(*args, **kwargs):
print(args)
print(kwargs)
# do something with the required1 and required2 ...
return fn(*args, **kwargs)
return wrapper
class MyClass(object):
def foo(self, a, b, required1=0, required2='x'):
pass
But calling the function in differernt ways the decorator wrapper would receive different argumets
A = MyClass()
A.foo(1, 2, 3, '4') # 1
A.foo(1, 2) # 2
A.foo(1, 2, required1=3, required2='4') # 3
The outputs would be like such:
#1
args: [<object at 0x0000>, 1, 2, 3, ‘4’]
kwargs: {}
#2
args: [<object at 0x0000>, 1, 2]
kwargs: {}
#3
args: [<object at 0x0000>, 1, 2]
kwargs: {‘required1’: 3, ‘required2’: ‘4’}
How am I supposed to do if I want to access the required arguments like r = kawrgs[‘required1’]
no matter the way of calling the function?
I've tried to solve this problem in one of my projects. And the only way I found is to use introspection of python.
Here is the code:
bound_args = inspect.signature(fn).bind(*in_args, **in_kwargs)
bound_args.apply_defaults()
target_args = dict(bound_args.arguments)
its binding income arguments of the function (either it comes with keywords or not) to the defined names of the function