Python local variables behaving strangely
Question:
Consider the following code:
def g():
a = {}
b = 0
def f():
a[0] = b
f()
print(a)
return a
a = g()
print(a)
It gives the following output when executed:
{0: 0}
{0: 0}
But if I try to update b
in f()
as in
def g():
a = {}
b = 0
def f():
a[0] = b
b+=1
f()
print(a)
return a
a = g()
print(a)
It throws the following error:
UnboundLocalError: local variable 'b' referenced before assignment
Is this expected? I need to update b
inside f()
. Is that impossible?
Answers:
You need to use the nonlocal
keyword:
def g():
a = {}
b = 0
def f():
nonlocal b
a[0] = b
b+=1
f()
print(a)
return a
a = g()
print(a)
This is because b += 1
is equal to b = b + 1
, so you’re assigning b
inside of the function f()
. Even though it’s later in the code, this will make it a local variable for the whole f()
function, and thus a[0] = b
will refer to the local b
which isn’t defined yet. Using nonlocal
tells the interpreter that there’s already a variable b
and it should be used in the function, instead of creating a new local variable.
Explicitly pass a
and b
to your function.
def g():
a = {}
b = 0
def f(a, b):
a[0] = b
b += 1
return b
b = f(a, b)
return a
Consider the following code:
def g():
a = {}
b = 0
def f():
a[0] = b
f()
print(a)
return a
a = g()
print(a)
It gives the following output when executed:
{0: 0}
{0: 0}
But if I try to update b
in f()
as in
def g():
a = {}
b = 0
def f():
a[0] = b
b+=1
f()
print(a)
return a
a = g()
print(a)
It throws the following error:
UnboundLocalError: local variable 'b' referenced before assignment
Is this expected? I need to update b
inside f()
. Is that impossible?
You need to use the nonlocal
keyword:
def g():
a = {}
b = 0
def f():
nonlocal b
a[0] = b
b+=1
f()
print(a)
return a
a = g()
print(a)
This is because b += 1
is equal to b = b + 1
, so you’re assigning b
inside of the function f()
. Even though it’s later in the code, this will make it a local variable for the whole f()
function, and thus a[0] = b
will refer to the local b
which isn’t defined yet. Using nonlocal
tells the interpreter that there’s already a variable b
and it should be used in the function, instead of creating a new local variable.
Explicitly pass a
and b
to your function.
def g():
a = {}
b = 0
def f(a, b):
a[0] = b
b += 1
return b
b = f(a, b)
return a