I have the following snippet of code:
def wrapper(func):
def wrapped(*args, **kwargs):
func.var = 0
return func(*args, **kwargs)
return wrapped
@wrapper
def f_out():
print(f_out.var)
Could you please explain to me why running f_out()
raises:
AttributeError: 'function' object has no attribute 'var'
EDIT
I had to elaborate, as an answer has given me the alternative but this will not work for the situation I want it. Given the following snippet:
def wrapper(func):
def wrapped(*args, **kwargs):
func.var = 0
ret = func(*args, **kwargs)
print(func.var)
return wrapped
@wrapper
def f_out():
f_out.var = 1
f_out()
print(f_out.var)
I get as output:
0
1
Why is this happening?
The correct way is to return the wrapped function and change it before returning it:
def wrapper(func):
def wrapped(*args, **kwargs):
return func(*args, **kwargs)
wrapped.var = 0
return wrapped
@wrapper
def f_out():
print(f_out.var)
You correctly get:
print(f_out())
gives
0
The updated snipped changes the var
attribute twice:
f_out
to 1. But at that moment, the function referenced as f_out
is the wrapped function and no longer the original one.So when you later print f_out.var
you print the attribute for the wrapped function which is 1.
Here is a slightly modified code demonstrating it:
def wrapper(func):
def wrapped(*args, **kwargs):
wrapped.orig = func # keeps a ref to the original function
func.var = 0
ret = func(*args, **kwargs)
print(func.var)
return wrapped
@wrapper
def f_out():
f_out.var = 1
f_out()
print(f_out.var, f_out.orig.var)
It prints
0
1 0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With