1

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?

2
  • stackoverflow.com/questions/1360721/… Commented Jun 19, 2020 at 1:05
  • The decorator makes almost no difference here (aside from ignoring the return value). Commented Jun 19, 2020 at 1:22

2 Answers 2

1

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)

Edit

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())
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the comment, however the point is to keep func_a as it is. I am trying to replicate someone else's work and make adjustment based on it, the only part of the code I have is similar to func_a but with hundreds more variables. For more complete information, @config used to be @obj.config in their original code, but I don't think obj is a class.
@JoeLiu I'm assuming that lr must be a file-wide global variable? Because ideally you could put that (and he other hundreds) in a class or something. Here's another idea, with only slight modification to func_a(): stackoverflow.com/a/11543718/12465821
The link you shared is very interesting. but I am not sure if the method would work if I were to separate the two functions into two files, like shown in the newly edited question above. I am also really interested in your ideal of putting the variables into a class? I tried it before but failed, Could you please share your idea of the implementation?
@JoeLiu I just edited my answer to include two ways of doing that.
This answer is really interesting, I think I can modify this to what I need. Thank you for your answer.
0

'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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.