Python: Change variable in function from a child/nested function? [duplicate] - python

This question already has answers here:
python: How do I capture a variable declared in a non global ancestral outer scope?
(5 answers)
Closed 8 years ago.
I have a function nested inside an other function. I want to change a variable inside the first function from the nested one.
def myfunc():
step=0
def increment():
step+=1
increment()
increment()
increment()
print("Steps so far:", step)
myfunc()
Gives
UnboundLocalError: local variable 'step' referenced before assignment
If I try and use global, it won't work either since it tries to dereference to a variable step outside myfunc which doesn't exist.
Is there a way to do this without having a global variable?

Declare step as a nonlocal variable. It will make the identifier refer the variable in enclosing scope.
def increment():
nonlocal step
step += 1
NOTE Python 3.x only.

Related

How to understand global and local scopes in Python? [duplicate]

This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Using global variables in a function
(25 answers)
Closed 5 months ago.
I am a novice in Python and wondering the situation below.
x = 1
def func():
print(x)
x = 2
return x
So I got the UnboundLocalError: local variable 'x' referenced before assignment.
But if I right understand - Python read and execute code row by row.
So in first statement inside function "print(x)" it must just relay global variable x which eq. 1, but instead I got the error.
Please explain, I think it simple.
I think your problem was explained as well in the FAQ of python docs
This is because when you make an assignment to a variable in a scope,
that variable becomes local to that scope and shadows any similarly
named variable in the outer scope. Since the last statement in foo
assigns a new value to x, the compiler recognizes it as a local
variable. Consequently when the earlier print(x) attempts to print the
uninitialized local variable and an error results.

How to set variable within function def in python? [duplicate]

This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
UnboundLocalError: local variable … referenced before assignment [duplicate]
(2 answers)
Closed 2 years ago.
I have a simple code like this:
temp = 100
def my_fun():
temp += 10
return temp
After I call this function my_fun() I get an error
local variable 'temp' referenced before assignment
What's wrong with my code? I set temp before I call it. But still an error.
Thanks to all.
Best would be to pass it in:
def my_fun(temp):
temp += 10
return temp
temp = 100
temp = my_fun(temp)
But if you really want to access it from the outer scope, then use:
global temp
Edit: I see you amended your question - the reason for the error is the scope of the var. Within the function that variable only exists at the function level, and since you've not actually assigned it or passed it in, it doesn't exist when you try and increment it.

Difference between two variable assignments in function scope modifying global vars [duplicate]

This question already has answers here:
Another UnboundLocalError in Python2.7 [duplicate]
(2 answers)
Closed 3 years ago.
What's the difference between doing:
m={}
i='a'
def change():
m['a'] = i
i = 'b'
Which raises an attribute error:
>>> change()
UnboundLocalError: local variable 'i' referenced before assignment
And:
m={}
i='a'
def change():
m['a'] = i
Which evaluates without an error.
>>> change()
>>> m
{'a': 'a'}
(Finally, a question about this question -- when is it appropriate to use the "yellow background" in the questions?)
This is answered in depth in the docs:
This is because when you make an assignment to a variable in a scope, that variable becomes local to that scope and shadows any similarly named variable in the outer scope. Since the last statement in foo assigns a new value to x, the compiler recognizes it as a local variable. Consequently when the earlier print(x) attempts to print the uninitialized local variable and an error results.
And the yellow background is stylistic but is generally used for quotes from somewhere but also can be used for any reason you want to break that text away from the main body or text or code.

UnBoundLocalError in Python while printing global variable [duplicate]

This question already has answers here:
Using global variables in a function
(25 answers)
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Closed 5 years ago.
Why is this code giving 'UnboundLocalError: local variable 'num1' referenced before assignment' error?
num1=50
def func():
print(num1)
num1=100
func()
Another gotcha! of python. This is because of hoisting and variable shadowing. If you have a local and global variable with the same name in a particular scope, the local variable will shadow the global one. Furthermore, declarations are hoisted to the top of their scope.
So your original code will look something like this:
num1=50
def func():
num1 = ... # no value assigned
print(num1)
num1=100
func()
Now, if you try to print num1 without having assigned any value to it, it throws UnboundLocalError since you have not bound any value to the variable at the time you are trying to dereference it.
To fix this, you need to add the global keyword to signify that num1 is a global variable and not local.
num1=50
def func():
global num1
print(num1)
num1=100
func()

When does my function will go to previous scopes to look for a variable? [duplicate]

This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Is it possible to modify a variable in python that is in an outer (enclosing), but not global, scope?
(9 answers)
Closed 6 months ago.
in python 3.0 from what i know when i'm using variables that aren't found in the local scope it will go all the way back until it reaches the global scope to look for that variable.
I have this function:
def make_withdraw(balance):
def withdraw(amount):
if amount>balance:
return 'insuffiscient funds'
balance=balance-amount
return balance
return withdraw
p=make_withdraw(100)
print(p(30))
When i insert a line:
nonlocal balance
under the withdraw function definition it works well,
but when i don't it will give me an error that i reference local variable 'balance' before assignment, even if i have it in the make_withdraw function scope or in the global scope.
Why in other cases it will find a variable in previous scopes and in this one it won't?
Thanks!
There are too many questions on this topic. You should search before you ask.
Basically, since you have balance=balance-amount in function withdraw, Python thinks balance is defined inside this function, but when code runs to if amount>balance: line, it haven't seen balance's definition/assignment, so it complains local variable 'balance' before assignment.
nonlocal lets you assign values to a variable in an outer (but non-global) scope, it tells python balance is not defined in function withdraw but outside it.

Categories