SpongeB0B
(SpongeBOB)
October 23, 2024, 10:08am
1
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.
Rosuav
(Chris Angelico)
October 23, 2024, 10:11am
2
A function’s default arguments are stored in the __defaults__
attribute (or __kwdefaults__
for kwonly arguments). Try printing out initial.__defaults__
.
1 Like
SpongeB0B
(SpongeBOB)
October 23, 2024, 10:19am
3
Thank you very much __defaults__
give me : (1,)
but I would like access/change them by name rather than by index… is it possible ?
Rosuav
(Chris Angelico)
October 23, 2024, 10:21am
4
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.
SpongeB0B
(SpongeBOB)
October 23, 2024, 11:14am
5
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…
Rosuav
(Chris Angelico)
October 23, 2024, 11:22am
6
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()