1
def square():
    print(a)
    a = 10
    b = a*a
    return b

a = 2

print(square())

UnboundLocalError: local variable 'a' referenced before assignment

def square():
    print(a)
    #a = 10
    b = a*a
    return b

a = 2

print(square())

I just want to make sure why the second scenario is right while the first is wrong.

The execution of a function introduces a new symbol table used for the local variables of the function. More precisely, all variable assignments in a function store the value in the local symbol table; whereas variable references first look in the local symbol table, then in the local symbol tables of enclosing functions, then in the global symbol table, and finally in the table of built-in names.

While interpreter is going through the definition of the function it creates a symbol table. It first thinks 'a' as global(due to print(a)) and later creates 'a' in local symbol table(Due to assignment).

So while actually executing the function, 'a' is a local which has no binding. Hence the error.

Is my reasoning right about symbol tables??

Update: Adding global after assignment:

def square():
    print(a)
    a = 10
    b = a*a
    global a
    return b

a = 2

print(square())

print(a)

Does global a statement remove name 'a' from the local symbol table of square function?

tez
  • 4,990
  • 12
  • 47
  • 67
  • 2
    Yep, that's my understanding as well. – Rami Oct 14 '13 at 08:10
  • possible duplicate of [Global and local variables in Python](http://stackoverflow.com/questions/14421733/global-and-local-variables-in-python) – devnull Oct 14 '13 at 08:21
  • Yeah the question might be a duplicate. But I wanted the discussion to be in terms of symbol tables – tez Oct 14 '13 at 08:52

1 Answers1

0

It's a scope issue. Check this answer : https://stackoverflow.com/a/293097/1741450

Variables in scopes other than the local function's variables can be accessed, but can't be rebound to new parameters without further syntax. Instead, assignment will create a new local variable instead of affecting the variable in the parent scope.

The first example is wrong since a cannot be modified.

Community
  • 1
  • 1
lucasg
  • 10,734
  • 4
  • 35
  • 57