Unbound variable and name

17,048

Solution 1

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 UnboudLocalError.

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, the name for a context manager in a with statement all bind names.

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.

Solution 2

One more place is when the variable is declared in global scope and if it is used in function scope, it should specifically refer as global otherwise UnboundLocalError occurs. Following is the example:

var = 123
def myfunc():
    var = var + 1
    print var

myfunc()

Error:

UnboundLocalError: local variable 'var' referenced before assignment
Share:
17,048
Admin
Author by

Admin

Updated on June 12, 2022

Comments

  • Admin
    Admin almost 2 years

    According to the python reference manual we have

    When a name is not found at all, a NameError exception is raised. If the name refers to a local variable that has not been bound, a UnboundLocalError exception is raised. UnboundLocalError is a subclass of NameError.

    I don't to understand when the UnboundLocalError is thrown? Because

    Python lacks declarations and allows name binding operations to occur anywhere within a code block.

    So how we can declare a variable, but not to initialize her?

  • Admin
    Admin about 10 years
    Very nice example, thanks! Does it mean that a specified block bindings are created before the code of this block is starting to execute?
  • Martijn Pieters
    Martijn Pieters about 10 years
    @Dmitrii: the compiler stores local names with the code block; this so the byte code can use the correct opcodes to load global names vs. local names vs. closures.
  • kindall
    kindall about 10 years
    Python decides whether a variable is local while compiling to byte code. If it's ever assigned to, it's local (unless there is a global or nonlocal declaration for it).
  • Martijn Pieters
    Martijn Pieters about 10 years
    @kindall: not just assignment; importing, function parameters, for loop targets, except and with clause as targets all bind names.
  • kindall
    kindall about 10 years
    You are technically correct... the best kind of correct. (In my mind all those are assignments, though.)
  • Martijn Pieters
    Martijn Pieters about 10 years
    @kindall: The reference manual calls it binding, then names assignment as an action that binds. Best to stick to the official terminology when writing answers on SO. :-)
  • Admin
    Admin about 10 years
    @Martijn Pieters Thanks for your answer, but I don't understand you. Where can I read about python bytecode instruction and how to compile sources to bytecode?