How can a name be "unbound" in Python? What code can cause an `UnboundLocalError`?
namespaces, python, variables
Solution
You can refer to a name without having assigned to it:
>>> foobar
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'foobar' is not defined
Here `foobar` is being referred to, but was never assigned to. This raises a `NameError` because the name was never bound.
More subtly, here assignment is not happening because the line that does is never run:
>>> def foo():
... if False:
... spam = 'eggs'
... print(spam)
...
>>> foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in foo
UnboundLocalError: local variable 'spam' referenced before assignment
Because `spam = 'eggs'` is never executed, `print(spam)` raises an `UnboundLocalError`.
Note that nowhere in Python is a name ever declared. You bind or don't bind, declaration is not part of the language.
Instead, binding is used to determine the scope of a name; binding operations include assignment, names used for a `for` loop, function parameters, import statements, name to hold a caught exception in an `except` clause, and the name for a context manager in a `with` statement.
If a name is bound in a scope (such as in a function) then it is a local name, unless you use a `global` statement (or a `nonlocal` statement in Python 3) to explicitly mark the name as a global (or a closure) instead.
So the following is an error:
>>> foo = None
>>> def bar():
... if False:
... foo = 'spam'
... print(foo)
...
>>> bar()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in bar
UnboundLocalError: local variable 'foo' referenced before assignment
because `foo` is being bound somewhere in the `bar` function scope. But if you mark `foo` as a global, the function works:
>>> foo = None
>>> def bar():
... global foo
... if False:
... foo = 'spam'
... print(foo)
...
>>> bar()
None
because now the Python compiler knows you wanted `foo` to be a global instead.
This is all documented in the Naming and Binding section of the Python reference documentation.
Problem
I read the following in the Python documentation: When a name is not found at all, a `NameError` exception is raised. If the current scope is a function scope, and the name refers to a local variable that has not yet been bound to a value at the point where the name is used, an `UnboundLocalError` exception is raised. `UnboundLocalError` is a subclass of `NameError`. ... Python lacks declarations and allows name binding operations to occur anywhere within a code block. I don't understand how this works. If there are no declarations, then when does `UnboundLocalError` get raised? How can the variable "not yet be bound" when it is encountered? See also UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use) for a common problem where a variable expected to be global, is local instead. This question is focused on cases where the programmer expects the variable to be local.
Related problems
- "UnboundLocalError: local variable referenced before assignment" after an if statement
- Why can't I call read() twice on an open file?
- How to use a global variable in a function?
- Why isn't the 'global' keyword needed to access a global variable?
- UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)