В этом разница между доступом к имени и привязкой внутри области.
Если вы просто ищете переменную, чтобы прочитать ее значение, у вас есть доступ кглобальная, а также локальная область.
Однако, если вы присваиваете переменную, имя которой не входит в локальную область, вы привязываете это имя к этой области (и если это имя также существуеткак глобальный, вы будете это скрывать).
Если вы хотите иметь возможность назначить глобальное имя, вы должны указать парсеру использовать глобальное имя, а не привязывать новое локальное имя - это то, что делает ключевое слово «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 "<pyshell#35>", line 1, in <module>
r()
File "<pyshell#32>", line 2, in r
print(a) # fail - a is bound to local scope, but not assigned yet
UnboundLocalError: local variable 'a' referenced before assignment
>>>