Python – Unexpected behaviour when accessing variable inside function that is defined outside function

Question:

This results in UnboundLocalError: cannot access local variable 'ans' where it is not associated with a value.

def a():
    ans = 4
    
    def traverse():
        if ans == 2:
            pass
        
        if True:
            ans = 3

    traverse()
    print(ans)
    
a()

This prints out 4:

def a():
    ans = 4
    
    def traverse():
        if ans == 2:
            pass

    traverse()
    print(ans)
    
a()

Why is it that in the second code there is no error on the ans == 2 line but in the first case there is?

Asked By: Devansh Sharma

||

Answers:

In the first example, ans is declared as a local variable within traverse, but because that’s after the first time it’s accessed, you get an error:

    def traverse():
        if ans == 2: # no local 'ans' exists yet!
            pass
        
        if True:
            ans = 3  # ans is a local var

In the second example, there is no assignment to ans inside of traverse, so the variable from the outer scope is used instead:

    def traverse():
        if ans == 2:  # 'ans' refers to the outer scope
            pass

What you might want to do is declare that ans is nonlocal, so that the assignment modifies the nonlocal var rather than creating a new var in the local scope:

def a():
    ans = 4
    
    def traverse():
        nonlocal ans

        if ans == 2: # accesses nonlocal ans
            pass
        
        if True:
            ans = 3  # rebinds nonlocal ans

    traverse()
    print(ans)  # prints 3
    
a()
Answered By: Samwise
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.