I have code like this (simplified):
def outer(): ctr = 0 def inner(): ctr += 1 inner()
But ctr
causes an error:
Traceback (most recent call last): File "foo.py", line 9, in <module> outer() File "foo.py", line 7, in outer inner() File "foo.py", line 5, in inner ctr += 1 UnboundLocalError: local variable 'ctr' referenced before assignment
How can I fix this? I thought nested scopes would have allowed me to do this. I've tried with 'global', but it still doesn't work.
Nested functions can access variables of the enclosing scope. In Python, these non-local variables are read-only by default and we must declare them explicitly as non-local (using nonlocal keyword) in order to modify them. Following is an example of a nested function accessing a non-local variable.
The Python "UnboundLocalError: Local variable referenced before assignment" occurs when we reference a local variable before assigning a value to it in a function. To solve the error, mark the variable as global in the function definition, e.g. global my_var .
UnboundLocalError can be solved by changing the scope of the variable which is complaining. You need to explicitly declare the variable global. Variable x's scope in function printx is global. You can verify the same by printing the value of x in terminal and it will be 6.
The nonlocal keyword is used to work with variables inside nested functions, where the variable should not belong to the inner function. Use the keyword nonlocal to declare that the variable is not local.
If you're using Python 3, you can use the nonlocal
statement to enable rebinding of a nonlocal name:
def outer(): ctr = 0 def inner(): nonlocal ctr ctr += 1 inner()
If you're using Python 2, which doesn't have nonlocal
, you need to perform your incrementing without barename rebinding (by keeping the counter as an item or attribute of some barename, not as a barename itself). For example:
... ctr = [0] def inner(): ctr[0] += 1 ...
and of course use ctr[0]
wherever you're using bare ctr
now elsewhere.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With