Курс по Python: https://stepik.org/course/100707
На этом занятии мы поговорим о работе с глобальными и локальными данными, то есть, фактически, об
области видимости переменных.
Когда мы
начинаем писать какую-либо программу и сохраняем ее в файле, например, с
названием:
myprog.py
то в Python автоматически
создается пространство имен с названием myprog (слайд). Изначально
оно пустое, но если там задать какие-либо переменные:
N = 100
WIDTH, HEIGHT = 1000, 500
то в этом
пространстве появятся эти имена (ссылки). Так вот, все переменные, которые
находятся непосредственно в этом пространстве имен, являются глобальными в
пределах текущего программного модуля. То есть, они доступны в любом месте
данной программы, после их объявления.
Добавим в эту
программу еще и функцию, пусть она будет такой:
def my_func(lst):
for x in lst:
n = x + 1
print(n)
В этом случае в
пространстве имен появится переменная my_func – ссылка на
объект-функцию, причем эта функция образует свое, локальное пространство имен с
названием my_func. И внутри этого
локального пространства автоматически появляются переменные lst, x и n. Обратите
внимание, цикл for не образовывает своего локального пространства,
только функция и все переменные внутри цикла находятся в области видимости
функции.
Как вы уже
догадались, переменные внутри локальной области видимости, называются
локальными и доступны только в ее пределах. Например, вне функции мы не можем
обращаться к локальным переменным lst, x и n. Строчка кода:
приведет к
ошибке – x не определена. А
вот внутри функции все три переменные существуют:
Если теперь
вызвать функцию:
то мы увидим
значения этих локальных переменных. Также внутри функции доступны все
переменные из внешней области видимости, в данном случае, глобальной. Если
записать:
то значения этих
переменных будут отображены.
А что будет,
если мы внутри функции определим локальную переменную N, то есть, с тем
же именем, что и глобальная переменная? Давайте попробуем:
def my_func(lst):
N = 10
…
В этом случае
будет использоваться именно локальная переменная N, созданная в
области видимости функции. То есть, алгоритм поиска переменных здесь такой.
Сначала идет обращение к локальной области видимости и если переменная с нужным
именем находится, то она и используется. Если же требуемая переменная не
существует в локальной области, то поиск переходит на следующий уровень к
внешней области и продолжается там. Поэтому, при отсутствии локальной
переменной N внутри функции,
берется глобальная переменная N из внешней области видимости. При этом,
значение глобальной переменной никак не меняется, так как мы ее не используем:
my_func([1, 2, 3])
print(N)
Хорошо, а как
нам тогда изменять значения глобальных переменных внутри функции, если попытка
присвоить ей какое-либо значение приводит к созданию аналогичной локальной
переменной? Для этого в программе нужно явно указать, что мы хотим работать
именно с глобальной переменной. Это делается с помощью ключевого слова global, за которым
перечисляются имена глобальных переменных, например, так:
def my_func(lst):
global N
…
Теперь имя N – это имя
глобальной переменной и ее изменение внутри функции приведет к изменению и
глобального значения.
Однако, здесь
следует быть аккуратным, если в функции уже была создана локальная переменная N, то конструкция
global приведет к
ошибке:
Так можно делать
только в отсутствии соответствующих локальных переменных.
Интересно, что
если сейчас глобальную переменную N поставить в комментарий:
то есть, она не
будет существовать изначально в программе, то после выполнения функции с
конструкцией global N, эта глобальная
переменная будет создана.
В Python имеется еще один
интересный режим работы с локальными переменными с использованием ключевого слова
nonlocal. Давайте
предположим, что у нас имеется объявление одной функции внутри другой (так тоже
можно делать):
x = 0
def outer():
x = 1
def inner():
x = 2
print("inner:", x)
inner()
print("outer:", x)
outer()
print("global:", x)
При запуске
программы мы увидим ожидаемые результаты, так как берутся локальные переменные
внутри каждой функции:
inner: 2
outer: 1
global: 0
А теперь представим,
что внутри функции inner мы хотели бы работать с переменной x, объявленной
уровнем выше, то есть, в функции outer. Для этого в локальной области этой
функции следует прописать ключевое слово nonlocal и указать
переменную, которую следует взять из внешней области видимости:
Теперь строка x = 2 будет
означать изменение переменной x в функции outer и при запуске
программы получим результаты:
inner: 2
outer: 2
global: 0
Но так можно
делать только с локальными переменными. С глобальной работать не будет. Если мы
пропишем строчку
в функции outer, то возникнет
ошибка, т.к. уровнем выше находится уже глобальная область. Здесь, вместо nonlocal следует уже
использовать global:
а nonlocal в inner убрать, иначе
опять же получится ссылка на глобальную переменную.
Теперь вы знаете,
что такое глобальные и локальные переменные, как к ним обращаться и как
использовать ключевые слова global и nonlocal. Для
закрепления материала вас ждут практические задания, а я ухожу в следующий
урок.
Курс по Python: https://stepik.org/course/100707