I can get but not set value of a variable wrapped by function. Why? | Sololearn: Learn to code for FREE!
New course! Every coder should learn Generative AI!
Try a free lesson
0

I can get but not set value of a variable wrapped by function. Why?

I would like to change a variable each time the wrapped function is called (and print it). When the variable value is got, all works fine. But when try to set a new value to it, a error occurs. Why this behavior? https://code.sololearn.com/cb8QlPIsVf38/?ref=app (see the code above)

10th Apr 2020, 4:28 PM
Daniel Bandeira
Daniel Bandeira - avatar
4 Answers
+ 5
Outer variables are readonly when you access to it from inner functions. You can read them. But if you make assignment to some variable in a function Python creates new local variable (if local with that name doesn't already exist) even if you use name of outer variable. You should use nonlocal keyword to say Python that you want to use nonlocal variable. Yes, you can declare function in one block: do the check if an attribute already exists in a function dictionary and if it doesn't then create it: def decor(func): if 'I' not in decor.__dict__: decor.I = 0 def wrap(): print("============") func() print("============") print(str(decor.I)) """delete the next line and run again the code""" decor.I += 4 return wrap
10th Apr 2020, 5:59 PM
andriy kan
andriy kan - avatar
+ 8
You can declare I as nonlocal: def decor(func): I=0 def wrap(): nonlocal I print("============") func() print("============") print(str(I)) """delete the next line and run again the code""" I=4 return wrap In this case every wrapped function will have it own variable "I": #..... print_text = decor(print_text) Pn=decor(nardia) print_text() # first call prints I = 0 print_text() # the next call prints I = 4 Pn() # first call prints I = 0 again as Pn has its own I Pn() # the next call prints I = 4 If you want to use the same variable for every function wrapped with decor then declare it as function attribute: def decor(func): def wrap(): print("============") func() print("============") print(str(decor.I)) """delete the next line and run again the code""" decor.I += 4 return wrap decor.I = 0
10th Apr 2020, 5:16 PM
andriy kan
andriy kan - avatar
0
Python Pip, I don't understand you. If a get the variable inside the function (as showed in the code) I can use the variable. I don't understand why I can't change it. And, if I do as you said, I would doing clearly runnable mistake.
10th Apr 2020, 5:24 PM
Daniel Bandeira
Daniel Bandeira - avatar
0
Andriy Kan, your answer works fine. Thank you. But I still didn't get why I can get the value "I" but not set it in the original code. Is there a less cumbersome way to achieve the wrapper you wrote? It's seems to me that is not cool declaring a function in many parts (blocks).
10th Apr 2020, 5:34 PM
Daniel Bandeira
Daniel Bandeira - avatar