x = 1
def fn():
print x
fn()
This prints "1":
x = 1
def fn():
x += 1
print x
fn()
This raises "UnboundLocalError: local variable 'x' referenced before assignment"
What is going on here?
x = 1
def fn():
print x
fn()
This prints "1":
x = 1
def fn():
x += 1
print x
fn()
This raises "UnboundLocalError: local variable 'x' referenced before assignment"
What is going on here?
In Python, assigning to a variable is also an implicit local declaration, that is resolved during the bytecode compilation. So
x += 1
will create a local variable x
and compile to this byte code:
0 LOAD_FAST 0 (x)
3 LOAD_CONST 1 (1)
6 INPLACE_ADD
7 STORE_FAST 0 (x)
The command LOAD_FAST
will try to load a local variable x
which is not yet defined, that's why it fails.
However, if you define x
as global
explicitly, then it will use LOAD_GLOBAL
/STORE_GLOBAL
instead.
In the case of print
in your first function, the compiler assumes that since no local variable is declared (assigned) ever in the function body, you should mean a global variable.
The act of assigning to a name, anywhere inside a function, makes that name local only.
You're using a local
variable , a different binding, not the global one.
A scope defines the visibility of a name within a block. If a local variable is defined in a block, its scope includes that block. If the definition occurs in a function block, the scope extends to any blocks contained within the defining one, unless a contained block introduces a different binding for the name
Because you have to add global x
to the function:
def fn():
global x
x += 1
print x
This tells the interpreter that you intend to modify a global variable. This is not necessary for certain objects like mutable sequences (e.g. list
).