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

Последнее обновление: 24.01.2022

Область видимости или scope определяет контекст переменной, в рамках которого ее можно использовать. В Python есть два типа контекста: глобальный и локальный.

Глобальный контекст

Глобальный контекст подразумевает, что переменная является глобальной, она определена вне любой из функций и доступна любой функции в программе. Например:

name = "Tom"


def say_hi():
    print("Hello", name)


def say_bye():
    print("Good bye", name)

say_hi()
say_bye()

Здесь переменная name является глобальной и имеет глобальную область видимости. И обе определенные здесь функции могут свободно ее использовать.

Локальный контекст

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

def say_hi():
    name = "Sam"
    surname = "Johnson"
    print("Hello", name, surname)


def say_bye():
    name = "Tom"
    print("Good bye", name)

say_hi()
say_bye()

В данном случае в каждой из двух функций определяется локальная переменная name. И хотя эти переменные называются одинаково, но тем не менее это две разных переменных, каждая из которых доступна только в рамках своей функции. Также в функции say_hi() определена переменная surname, которая также является локальной, поэтому в функции say_bye() мы ее использовать не сможем.

Скрытие переменных

Есть еще один вариант определения переменной, когда локальная переменная скрывают глобальную с тем же именем:

name = "Tom"


def say_hi():
    name = "Bob"        # скрываем значение глобальной переменной
    print("Hello", name)


def say_bye():
    print("Good bye", name)


say_hi()    # Hello Bob
say_bye()   # Good bye Tom

Здесь определена глобальная переменная name. Однако в функции say_hi определена локальная переменная с тем же именем name. И если функция say_bye использует глобальную переменную, то функция say_hi использует локальную переменную, которая скрывает глобальную.

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

name = "Tom"


def say_hi():
    global  name
    name = "Bob"        # изменяем значение глобальной переменной
    print("Hello", name)


def say_bye():
    print("Good bye", name)


say_hi()    # Hello Bob
say_bye()   # Good bye Bob

nonlocal

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

def outer():  # внешняя функция
    n = 5

    def inner():    # вложенная функция
        print(n)

    inner()     # 5
    print(n)


outer()     # 5

Здесь вложенная локальная функция inner() выводит на консоль значение переменной n, которая определена во внешней функции outer(). Затем в функции outer() вызывается внутренняя функция inner().

При вызове функции outer() здесь мы ожидаемо увидим на консоли два раза число 5. Однако в данном случае вложенная функция inner() просто получает значение. Теперь возьмем другую ситуацию, когда вложенная функция присваивает значение переменной:

def outer():  # внешняя функция
    n = 5

    def inner():    # вложенная функция
        n = 25
        print(n)

    inner()     # 25
    print(n)


outer()     # 5 
# 25    - inner
# 5     - outer

При присвоении значения во вложенной функции: n = 25 будет создаваться новая переменная n, которая скроет переменную n из окружающей внешней функции outer. В итоге мы получим при выводе два разных числа. Чтобы во вложенной функции указать, что идентификатор во вложенной функции будет представлять переменную из окружающей функции, применяется выражение nonlocal:

def outer():  # внешняя функция
    n = 5

    def inner():    # вложенная функция
        nonlocal n  # указываем, что n - это переменная из окружающей функции
        n = 25
        print(n)

    inner()     # 25
    print(n)


outer()          # 25
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850