JimPri
JimPri

Reputation: 1407

Python: Nested function naming conflict

I recently encountered an error with the following python code:

def foo():
    print("Global")

def func():
    foo() # This causes an error, but only if foo() is redefined
    def foo():
        print("Nested")

func()

I naively expected this to print "Global", since the call to foo() occurs before it is redefined within the scope of func(). However, that line raises this error:

UnboundLocalError: local variable 'foo' referenced before assignment

It seems like the interpreter treats the call to foo() differently based on the future naming conflict, and it has to due with this being within a function since in-lining the call to foo() and the redefinition doesn't have the same behavior.

QUESTION: What is happening under the covers in this scenario? I've found several other questions/answers regarding local vs global variables but nothing regarding local functions like this. Thanks!

ANSWER: The interpreter first determines whether each variable in a function is local or global based on its use before it executes the function call. The act of defining foo() inside func() makes it local, so the call to it breaks. The same holds true for this simpler example:

x = 9
def func():
    print(x)
    x=5 # This statement makes 'x' local, so the previous line throws

func()

Upvotes: 1

Views: 379

Answers (1)

blhsing
blhsing

Reputation: 106891

This is because the Python compiler looks at all the l-values in a code block when determining which variables are local at compilation time rather than at run time, so the fact that foo is defined in func anywhere makes foo local to that code block. You there can't reference it before it is defined in func.

Upvotes: 2

Related Questions