I am trying to find a way to pass my functions default arguments to the decorator. I have to say I am fairly new to the decorator business, so maybe I just don't understand it properly, but I have not found any answers yet.
So here my modified example from the python functools.wraps manual page.
from functools import wraps
def my_decorator(f):
@wraps(f)
def wrapper(*args, **kwds):
print 'Calling decorated function'
print 'args:', args
print 'kwargs:', kwds
return f(*args, **kwds)
return wrapper
@my_decorator
def example(i, j=0):
"""Docstring"""
print 'Called example function'
example(i=1)
I want the j=0
to be passed, too. So that the output should be:
Calling decorated function
args: ()
kwargs: {'i': 1, 'j': 0}
Called example function
You can get default argument values by using __defaults__
special attribute.
def my_decorator(f):
@wraps(f)
def wrapper(*args, **kwds):
print('def args values', f.__defaults__)
return f(*args, **kwds)
return wrapper
Reference: look for __defaults__
in https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy
A tuple containing default argument values for those arguments that have defaults, or None if no arguments have a default value
Default argument is part of function signature. Its not exists in decorator call.
So to use it in wrapper you need to get it out like shown in this question.
import inspect
from functools import wraps
def get_default_args(func):
signature = inspect.signature(func)
return {
k: v.default
for k, v in signature.parameters.items()
if v.default is not inspect.Parameter.empty
}
def my_decorator(f):
@wraps(f)
def wrapper(*args, **kwds):
print('Calling decorated function')
print('args:', args)
kwargs = get_default_args(f)
kwargs.update(kwds)
print('kwargs:', kwargs)
return f(*args, **kwds)
return wrapper
@my_decorator
def example(i, j=0):
"""Docstring"""
print('Called example function')
example(i=1)
Output:
Calling decorated function
args: ()
kwargs: {'i': 1, 'j': 0}
Called example function