По умолчанию присвоение имени всегда действует на локальную переменную, создавая новую, если она еще не определена.
Оператор global
делает имя ссылкой переменной в глобальной области, позволяющей вам присвоить глобальное имя, не создавая новую локальную переменную.
(оператор nonlocal
делает нечто подобное, за исключением того, что имя ссылается на переменную, определенную в ближайшая ограничивающая область, которая не обязательно является глобальной областью действия.)
В первом примере вы не назначаете имя; вы выполняете поиск атрибутов для свободной переменной, которая преобразуется в глобальную переменную с тем же именем.
Во втором примере вы пытаетесь создать новую локальную переменную. Поскольку область действия определяется во время компиляции, a = a + [1]
завершится ошибкой, поскольку a
в правой части будет по-прежнему ссылаться на еще не определенную локальную переменную a
. При global
присвоение не создает локальную переменную, поэтому правая часть является выражением, включающим глобальную переменную, а результат также присваивается глобальному имени.