Reputation: 13
I am trying to use decorator to modify variable value in python with the following code
def config(func):
def new_function():
func()
print(lr)
return new_function
import ex
@ex.config
def config():
lr = 0.1
globals().update(locals())
config()
I would like to print out 0.1, but error with variable not defined was shown.
Is there anyway to achieve this without changing func_a
?
Upvotes: 1
Views: 555
Reputation: 498
In short, no.
What is happening here is func_a()
is declaring and assigning lr
as a local variable.
You can fix this by adding the global
keyword:
lr = 0
def config(func):
def new_function(*args,**kwargs):
func(*args,**kwargs)
return new_function
@config
def func_a():
global lr
lr = 0.1
func_a()
print(lr)
But using the global
keyword is annoying and can cause bugs if you forget it, so you might be better off returning:
lr = 0
def config(func):
def new_function(*args,**kwargs):
return func(*args,**kwargs)
return new_function
@config
def func_a():
return 0.1
lr = func_a()
print(lr)
You could put it in a class somehow like this:
# Make an empty class:
class Foo: pass
# Or if you want to initalize the variables:
class Foo:
def __init__(self):
lr = 0
f = Foo()
# The decorator doesn't make much of a difference
def func_a():
f.lr = 0.1
func_a()
print(f.lr)
Now, if you want to keep absolutely all the local variables that func_a
defines, you could do this:
def func_a():
lr = 0.1
f.__dict__.update(locals())
Upvotes: 1
Reputation: 33
'lr' is an local variable and you didn't save or return its value.So you just can get the value of global variable 'lr' in the first line and its value is 0.
Upvotes: 0