a = 10
print(a) # UnboundLocalError raised here
a = 20
UnboundLocalError: local variable 'a' referenced before assignment
This is because according to Python's documentation, the interpreter will notice an assignment for the global variable in the scope, then from this point recognize the variable
a as a local variable, therefore shadowing the global
The exception is then raised "early", because the interpreter, still executing the code "line by line", will encounter the print statement referencing a local variable, which is not yet bound.
As you mentioned in your question, one has to use the
global keyword to explicitly tell the compiler that the assignment in this scope is done to the global variable the correct code would be:
a = 10 def f(): global a print(1) print(a) # Prints 10 as expected a = 20 f()
As @2rs2ts said in a now-deleted answer, this is easily explained by the fact that "Python is not merely interpreted, it is compiled into a bytecode and not just interpreted line by line".