david
david

Reputation: 954

In python, how to obtain the default parameter of a function within the decorator?

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

Answers (1)

Mad Physicist
Mad Physicist

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

Related Questions