Modify a function through a decorator

Hi,

def addon(func):
	func.__dict__['test'] = 2

	return func


@addon
def initial(test=1):
	print("I'm initial with test " + str(test))


initial()

give me as output

I’m initial with test 1

I was expecting " I’m initial with test 2 "

How can I change the kwarg of the decorated function ? (with the less lines possibles, so meaning without a wrapper ?!

Thanks.

A function’s default arguments are stored in the __defaults__ attribute (or __kwdefaults__ for kwonly arguments). Try printing out initial.__defaults__.

1 Like

Thank you very much __defaults__ give me : (1,)

but I would like access/change them by name rather than by index… is it possible ?

You can make it a keyword-only parameter, and then it’ll be in __kwdefaults__ by name instead. Otherwise, you’ll have to match it up with what you find from the variable names.

indeed

def addon(func):
	print(func.__kwdefaults__)
	func.__dict__['test'] = 2
	return func

@addon
def initial(*,test=1):
	print("I'm initial with test " + str(test))

initial()

{‘test’: 1}
I’m initial with test 1

So I can’t still change the test kwarg with the addon decorator… :confused:

Do you notice what’s going on here? Setting the function’s dictionary is NOT changing its local variables.

1 Like

Hello,

can you use a class as the decorator:

class addon:

    def __init__(self, func):                                     
        self.func = func

    def __call__(self, *args):   
        return self.func(2)      # Change value here as the argument

@addon
def spam(test = 1):               
                                
    print("I'm initial with test: ", test)

spam()