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)
4 odpowiedzi
+ 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
+ 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
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.
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).