When you use a variable in Python, it's first looked up in the current scope. If no such variable is found, the next enclosing scope is searched. That is repeated until the global namespace is reached.
x = 1
def scope():
x = 2
def inner_scope():
print(x) # prints 2
inner_scope()
scope()
However, the variable assignment doesn't work the same way. The new variable is always created in the current scope unless global or nonlocal is specified:
x = 1
def scope():
x = 2
def inner_scope():
x = 3
print(x) # prints 3
inner_scope()
print(x) # prints 2
scope()
print(x) # prints 1global allows using variables of global namespaces while nonlocal searches for the variable in the nearest enclosing scope. Compare:
x = 1
def scope():
x = 2
def inner_scope():
global x
x = 3
print(x) # prints 3
inner_scope()
print(x) # prints 2
scope()
print(x) # prints 3x = 1
def scope():
x = 2
def inner_scope():
nonlocal x
x = 3
print(x) # prints 3
inner_scope()
print(x) # prints 3
scope()
print(x) # prints 1