>>>> def change_and_print_global():
>…·····print('inside change_and_print_global:', animal)
>…·····animal = 'wombat'
>…·····print('after the change:', animal)
>…
>>>> change_and_print_global()
>Traceback (most recent call last):
>··File "", line 1, in
>··File "", line 2, in change_and_report_it
>UnboundLocalError: local variable 'animal' referenced before assignment
Если вы просто измените его, изменится другая переменная, которая также называется animal, но находится внутри функции:
>>>> def change_local():
>…·····animal = 'wombat'
>…·····print('inside change_local:', animal, id(animal))
>…
>>>> change_local()
>inside change_local: wombat 4330406160
>>>> animal
>'fruitbat'
>>>> id(animal)
>4330390832
Что здесь произошло? В первой строке мы присвоили строку 'fruitbat' глобальной переменной с именем animal. Функция change_local() также имеет переменную с именем animal, но она находится в ее локальном пространстве имен.
Мы использовали функцию id(), чтобы вывести на экран уникальное значение каждого объекта и доказать, что переменная animal, расположенная внутри функции change_local(), — это не переменная animal, расположенная на основном уровне программы.
Чтобы получить доступ к глобальной переменной вместо локальной переменной внутри функции, вам нужно явно использовать ключевое слово global (вы знали, что я это скажу: явное лучше неявного):
>>>> animal = 'fruitbat'
>>>> def change_and_print_global():
>…·····global animal
>…·····animal = 'wombat'
>…·····print('inside change_and_print_global:', animal)
>…
>>>> animal
>'fruitbat'
>>>> change_and_print_global()
>inside change_and_print_global: wombat
>>>> animal
>'wombat'
Если вы не используете ключевое слово global внутри функции, Python задействует локальное пространство имен и переменная будет локальной. Она пропадет после того, как функция завершит работу.
Python предоставляет две функции для доступа к содержимому ваших пространств имен:
• locals() — возвращает словарь, содержащий имена локального пространства имен;
• globals() — возвращает словарь, содержащий имена глобального пространства имен.
Вот так они используются:
>>>> animal = 'fruitbat'
>>>> def change_local():
>…·····animal = 'wombat'··# локальная переменная
>…·····print('locals:', locals())
>…
>>>> animal
>'fruitbat'
>>>> change_local()
>locals: {'animal': 'wombat'}
>>>> print('globals:', globals()) # немного переформатировано для представления
>globals: {'animal': 'fruitbat',
>'__doc__': None,
>'change_local': ,
>'__package__': None,
>'__name__': '__main__',
>'__loader__': ,