Страницы

Поиск по вопросам

четверг, 19 декабря 2019 г.

Почему из функции недоступна глобальная переменная?

#python #python_3x #python_faq


Подскажите пожалуйста почему функция не выводит в консоль значение s

s = "I'm global variable"

def foo():
    print(s)
    s = 'Reset global variable'

foo()


Я предполагал, что когда интерпретатор дойдёт до строки print(s), он поймёт, что
в области видимости функции foo такой переменной не существует. Следовательно начнёт
искать её во внешней области видимости, но там она есть.

Однако в результате в консоль выводится следующее сообщение об ошибке:

Traceback (most recent call last):
  File "index.py", line 7, in 
    foo()
  File "index.py", line 4, in foo
    print(s)
UnboundLocalError: local variable 's' referenced before assignment


Проблема исчезает, если закомментировать строку 

s = 'Reset global variable'


но мне всё равно не понятен механизм
    


Ответы

Ответ 1



Марк Лутц - "Изучаем Python", глава 20, страница 596 Как известно, имена, которым выполняется присваивание внутри функции, по умолчанию рассматриваются как локальные – они располагаются в области видимости функции и существуют только во время работы функции. Но я еще не говорил, что локальные переменные определяются статически, во время компиляции программного кода в инструкции def, а не в соответствии с операциями присваивания, производимыми во время выполнения. Эта особенность становится причиной появления самых причудливых сообщений в группе новостей, получаемых от начинающих программистов. Обычно, если внутри функции имени не присваивается какое-либо значение, поиск его будет производиться в области видимости объемлющего модуля. Но посмотрите, что произойдет, если добавить инструкцию присваивания переменной X после ее использования. X = 99 >>> def selector(): ... print(X) # Переменная еще не существует! ... X = 88 # X классифицируется как локальная переменная ... # То же самое происходит при “import X”, “def X”... >>> selector() Traceback (most recent call last): ...текст сообщения об ошибке опущен... UnboundLocalError: local variable ‘X’ referenced before assignment Было получено сообщение о том, что переменная не определена, но причина его появления не очевидна. Этот программный код компилируется интерпретатором во время ввода в интерактивной оболочке или во время импорта модуля. Вовремя компиляции Python обнаруживает операцию присваивания переменной X и делает вывод, что X – это локальное имя везде в теле функции. Но во время выполнения функции, из-за того, что к моменту вызова инструкции print операция присваивания еще не производилась, интерпретатор сообщает о том, что имя не определено. Согласно этому правилу использования имен, он говорит, что обращение к локальной переменной X произведено до того, как ей было присвоено значение. Фактически любая операция присваивания внутри функции создает локальное имя. Операция импортирования, =, вложенные инструкции def, вложенные определения классов и так далее – все трактуются именно таким образом. Проблема возникает из-за того, что операция присваивания делает имена локальными для всей функции, а не только для той ее части, которая следует за инструкцией присваивания. Читать учебники - полезно.

Ответ 2



В вашем коде не хватает объявления, что вы планируете использовать глобальную переменную локально с помощью директивы global. s = "I'm global variable" def foo(): global s # here we go! print(s) s = 'Reset global variable' foo()

Комментариев нет:

Отправить комментарий