Python UnboundLocalError

It could be surprising to see when you add assignment statement in the code and you started to get this UnboundLocalError error case.

Lets see how does Python internally handles this. Since, Python is Interpreted language this error has lot to do with how it identifies the scope of the variable. When python evaluates the particular block, it would idenify the scope of the variable by scanning the entire block.

UnboundLocalError Explained

 UnboundLocalError: local variable 'x' referenced before assignment
 

First we will understand what is this UnboundLocalError

1
2
3
4
5
6
    >>> x=10
    >>> def foo():
    ...     print(x)
    ...
    >>> foo()
    10
This should work fine

Now, lets add the assignment operator in this same code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
    >>> x=10
    >>> def foo():
    ...     print(x)
    ...     x += 1
    ...
    >>> foo()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in foo
    UnboundLocalError: local variable 'x' referenced before assignment

When we add line:4 x+=1 assignment operator in a scope, that variable becomes local to that scope and shadows the outer scope's same name. As a result of this, in line number 3 x is printed before its assignment operator. Hence, python is giving UnboundLocalError: local variable 'x' referenced before assignment

Solution

Visualization of execution

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
    >>> x=10
    >>> def foo():
    ...     global x
    ...     print(x)
    ...     x += 1
    ...
    >>> foo()
    10
    >>> print(x)
    11

By adding, global scope in line number 3, Python takes x as global scope and fixes this issue.

Rules for Scopes

  • Variables that are only referenced (E.g. print(x)) inside a function are implicitly global
  • If a variable is assigned a value (E.g. x += 1) anywhere within the function's body, it's assumed to be a local unless explicitly declared as global.

Actually executing with this example would give better perspective of how python handles its scopes. I will be start exploring Python's internal magic and it would be key learning process.