Why does this code raise UnboundLocalError even though x is defined globally?
Assigning to x anywhere inside a function makes x local to the whole function. Reading it before the assignment then fails with UnboundLocalError. Declare global x, or pass x in as an argument, to fix it.
Explain it simply
Python decides whether a name is local when it compiles the function, before running anything. If it sees x = ... anywhere in the body, it marks x as local for the entire function. A print of x on an earlier line is therefore asking for a local that has no value yet.
Example
x = 10
def broken():
print(x)
x = 5
try:
broken()
except UnboundLocalError:
print("UnboundLocalError") # Output: UnboundLocalError
def fine_read():
print(x) # Output: 10
fine_read()
def fine_global():
global x
print(x) # Output: 10
x = 5
fine_global()
print(x) # Output: 5fine_read only reads x, so Python finds the global. In broken, the later x = 5 flips the name to local.
What to say in the interview
"Local versus global is decided at compile time per function. Any assignment, including += and for-loop targets, makes the name local throughout that function, so an earlier read hits an unassigned local and raises UnboundLocalError. I fix it with global or nonlocal if rebinding is intended, or better, by passing values explicitly."