В этом разница между доступом к имени и привязке в пределах области.
Если вы просто просматриваете переменную, чтобы прочитать ее значение, у вас есть доступ к глобальным и локальным областям.
Однако, если вы назначаете переменной, имя которой не находится в локальной области, вы привязываете это имя в эту область (и если это имя также существует как глобальное, вы это скроете).
Если вы хотите назначить глобальное имя, вам нужно сказать парсеру, чтобы использовать глобальное имя, а не связывать новое локальное имя - это то, что делает ключевое слово «global».
Привязка в любом месте блока приводит к тому, что имя внутри этого блока становится привязанным, что может вызвать некоторые довольно странные последствия (например, UnboundLocalError внезапно появляется в предыдущем рабочем коде).
>>> a = 1
>>> def p():
print(a) # accessing global scope, no binding going on
>>> def q():
a = 3 # binding a name in local scope - hiding global
print(a)
>>> def r():
print(a) # fail - a is bound to local scope, but not assigned yet
a = 4
>>> p()
1
>>> q()
3
>>> r()
Traceback (most recent call last):
File "", line 1, in
r()
File "", line 2, in r
print(a) # fail - a is bound to local scope, but not assigned yet
UnboundLocalError: local variable 'a' referenced before assignment
>>>