Reputation: 954
I have built a series of functions and a decorator as follows:
def check_param(func):
def wrapper(param):
# check the param
check(param)
# then run the function
return func(param)
return wrapper
@check_param
def func_a(param='a'):
print(param)
@check_param
def func_b(param='b'):
print(param)
The parameter param
of the functions has different default values, and I need to check them before running print(param)
. However, sometimes the functions use default parameter, then how can I check the value of the parameter used in the functions before running it.
Update
I know the package inspect
can get the default values of the parameters. However, if I wrap the function with a decorator, inspect
only can get the default settings of the decorator (like the decorator check_param
) rather than the function func_a
. So it cannot solve my problem.
Upvotes: 0
Views: 601
Reputation: 114578
The default arguments for a function are stored in its __defaults__
and __kwdefaults__
attributes (see here: https://docs.python.org/3/reference/datamodel.html). Both are writable, so you can copy them over like this:
def check_param(func):
def wrapper(param):
# check the param
check(param)
# then run the function
func(param)
wrapper.__defaults__ = func.__defaults__
wrapper.__kwdefaults__ = func.__kwdefaults__
return wrapper
You can do it even cleaner using functools.wraps
, but the default assigned
will need to be updated with the attributes you want in addition to the usual WRAPPER_ASSIGNMENTS
:
from functools import wraps, WRAPPER_ASSIGNMENTS
def check_param(func):
@wraps(func, assigned=WRAPPER_ASSIGNMENTS + ('__defaults__', '__kwdefaults__'))
def wrapper(param):
# check the param
check(param)
# then run the function
func(param)
return wrapper
Upvotes: 2