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?

Asked By: Raghuram Vadapalli

||

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.

Answered By: Markus Meskanen

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
Answered By: Alexander
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.