In Python, the following code works:
a = 1
b = 2
def test():
print a, b
test()
And the following code works:
a = 1
b = 2
When you modify a
, it becomes a local variable. When you're simply referencing it, it is a global. You haven't defined a
in the local scope, so you can't modify it.
If you want to modify a global, you need to call it global in your local scope.
Take a look at the bytecode for the following
import dis
a = 9 # Global
def foo():
print a # Still global
def bar():
a += 1 # This "a" is local
dis.dis(foo)
Output:
2 0 LOAD_GLOBAL 0 (a)
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
For the second function:
dis.dis(bar)
Output:
2 0 LOAD_FAST 0 (a)
3 LOAD_CONST 1 (1)
6 INPLACE_ADD
7 STORE_FAST 0 (a)
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
The first function's bytecode loads the global a
(LOAD_GLOBAL
) because it is only being referenced. The second function's bytecode (LOAD_FAST
) tries to load a local a
but one hasn't been defined.
The only reason your second function works is because a
is equal to 1
. If a
was anything but 1
, the local assignment to b
wouldn't happen and you'd receive the same error.