1

The following snippet is an example where we face an UnboundLocalError when accessing a nonlocal variable.

def foo(): 
    a = 1 
    def bar(): 
        a += 1 # Raises UnboundLocalError
        print(a) 
    bar() 

foo()

a += 1 is evaluated as a = a+1. Here, the a on the RHS leads to an UnboundLocalError.

It can be fixed with the nonlocal keyword like so:

def foo(): 
    a = 1 
    def bar(): 
        nonlocal a # Fixes the UnboundLocalError
        a += 1 
        print(a) 
    bar() 

foo() # Prints 2

In the following snippet, we try to access a nonlocal list, but it does not raise an UnboundLocalError.

def egg(): 
    l = [[1 for _ in range(3)] for _ in range(3)] 
    def chicken(): 
        l[0][0] -= 1 # Does not raise an UnboundLocalError
        l[1][1] -= 1 
        l[2][2] -= 1 
        print(l) 
    chicken()

egg() # Prints [[0, 1, 1], [1, 0, 1], [1, 1, 0]]

The way I understand this, here as well, l[0][0] -= 1 should have been evaluated as l[0][0] = l[0][0]-1 which should have resulted in an UnboundLocalError. Why is that not the case?

  • 1
    You’re not *rebinding* any name by assigning to an index of a list. That’s the difference. – deceze Jun 27 '21 at 11:50

0 Answers0