Области видимости переменных

Области видимости переменных

На предыдущих занятиях я иногда произносил фразы: локальная переменнаяглобальная переменная. Давайте теперь подробнее разберемся что это за переменные и как с ними работать.

Если сказать по простому, то

Глобальная переменная – это переменная доступная в любом месте программы.

Как можно ее задать? Очень просто – в начале текстового файла, например:

a = 5

N = (100, )

WIDTH, HEIGHT = (1000, 500)

Однако, использование глобальных переменных считается плохим стилем программирования. И допускается, разве что, задавать глобальные константы, используемые во всей программе. А имена констант записывать заглавными буквами, чтобы отличать их от обычных не глобальных (то есть, локальных) переменных.

Локальные переменные – это переменные, объявленные внутри любого блока программы.

Например:

def myFunc(b):

    for x in range(b):

        n = x+1

        print(n, end=" ")

 

myFunc(6)

Здесь у нас сразу три локальных переменных: b, n, x. Почему локальные? Дело в том, что они доступны только внутри функции myFunc и не существуют за ее пределами. Если мы попытаемся после функции выполнить операцию, например:

print(x)

то возникнет ошибка, что x не существует. А вот внутри функции все три переменные существуют:

print(b, n, x)

Обратите внимание, здесь цикл for не образует своих локальных переменных, как это происходит, например, в С++ или Java, и вот эта переменная n продолжает существовать и за его пределами.

Ну, хорошо, а как мы можем работать с глобальной переменной внутри этой функции? Если написать вот такую конструкцию:

def myFunc(b):

    a = 10

    for x in range(b):

        n = x+1

        print(n, end=" ")

и после вызова этой функции вывести значение переменной a:

myFunc(6)

print("%d"%(a))

то увидим прежнее значение 5. Почему? Дело в том, что когда мы присвоили a=10, то внутри функции была создана локальная переменная с таким же именем a и на значение глобальной переменной это никак не повлияло.

Более наглядный пример использования локальной переменной с тем же именем, что и глобальная, такой:

ame = "Tom"

 

def say_hi():

    print("Hello", name)

 

def say_bye():

    name = "Bob"

    print("Good bye", name)

 

say_hi()

say_bye()

В консоли увидим:

Hello Tom
Good bye Bob

То есть, первая функция использовала глобальную переменную name, т.к. никакой другой для нее не существовало, а вторая функция использовала локальную name, объявленную внутри нее. Этот пример показывает, что функция сначала пытается найти нужную переменную внутри собственной области видимости, и если не находит, то переходит на более высокий уровень, в данном случае – глобальной области.

Если же мы хотим поменять именно глобальную переменную, то в функции следует вначале это явно сказать:

global a

тем самым мы указываем, что хотим работать с глобальной a, а не создавать локальную переменную. Теперь, при выполнении этой программы, мы видим измененное значение глобальной переменной a.

Однако, здесь следует быть аккуратным, так как если в функции уже была создана локальная a, то конструкция global приведет к ошибке:

    a = 5

    global a

Так можно делать только в отсутствии соответствующих локальных переменных.

Или же, если глобальная переменная a не существует и внутри функции мы выполняем эти операции, то будет создана глобальная переменная с соответствующим значением.

В Python имеется один интересный режим работы с локальными переменными с использованием ключевого слова onlocal. Давайте предположим, что у нас имеется объявление одной функции внутри другой:

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:

onlocal x

Теперь строка x=2 будет означать изменение переменной x в функции outer и при запуске программы получим результаты:

inner: 2
outer: 2
global: 0

Но так можно делать только с локальными переменными. С глобальной работать не будет. Если мы пропишем строчку

onlocal x

в функции outer, то возникнет ошибка, т.к. уровнем выше находится уже глобальная область. Здесь, вместо nonlocal следует уже использовать global:

global x

а nonlocal в inner убрать, иначе опять же получится ссылка на глобальную переменную.

Итак, на этом занятии мы с вами рассмотрели глобальную и локальную области видимости переменных и познакомились с ключевыми словами global и nonlocal.

icon