Когда необходимо глобальное утверждение? - PullRequest
0 голосов
/ 22 февраля 2020

Я немного озадачен «глобальным» утверждением.

«пример кода 1» работает нормально без использования оператора «global»; однако «пример кода 2» не будет запущен, если «глобальный а» не прокомментирован.

Почему я должен объявлять «глобальный» в «примере кода 2», а не в «примере кода 1» ?

# sample code 1

def updating():    
    a.append(1);    

if __name__=='__main__':
    a=[100];
    print(f'before updating, variable a id is {id(a)}, and value is {a}')
    updating()
    print(f'after  updating, variable a id is {id(a)}, and value is {a}')

# sample code 2

def updating(): 
    #global a 
    a=a+[1]

if __name__=='__main__':
    a=[100];
    print(f'before updating, variable a id is {id(a)}, and value is {a}')
    updating()
    print(f'after  updating, variable a id is {id(a)}, and value is {a}')

1 Ответ

1 голос
/ 22 февраля 2020

По умолчанию присвоение имени всегда действует на локальную переменную, создавая новую, если она еще не определена.

Оператор global делает имя ссылкой переменной в глобальной области, позволяющей вам присвоить глобальное имя, не создавая новую локальную переменную.

(оператор nonlocal делает нечто подобное, за исключением того, что имя ссылается на переменную, определенную в ближайшая ограничивающая область, которая не обязательно является глобальной областью действия.)

В первом примере вы не назначаете имя; вы выполняете поиск атрибутов для свободной переменной, которая преобразуется в глобальную переменную с тем же именем.

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

...