Сообщить об ошибке.

Функция locals() в Python, переменные локальной области

Возвращает словарь с переменными и их значениями локальной области видимости

Синтаксис:

locals()

Ссылка для тех, кто ищет инструкцию nonlocal.

Возвращаемое значение:

  • словарь dict, представляющий текущую локальную таблицу символов.

Описание:

Функция locals() обновляет и возвращает словарь с переменными и их значениями из текущей локальной области видимости.

Работа locals() в содержащей области видимости.

В области видимости модуля, а также при использовании exec() или eval() с одним пространством имен, функция locals() возвращает то же пространство имен, что и globals().

В области видимости класса, locals() возвращает пространство имен, которое будет передано конструктору метакласса.

При использовании exec() или eval() с отдельными локальными и глобальными аргументами возвращается локальное пространство имен, переданное при вызове функции.

Во всех вышеперечисленных случаях каждый вызов locals() в заданном фрейме выполнения будет возвращать один и тот же объект словаря/сопоставления. Внесенные изменения в словарь, возвращаемый из locals(), будут сразу видны и немедленно повлияет на содержимое возвращаемого объекта словаря/сопоставления.

Работа locals() в оптимизированной области видимости.

Оптимизированная область - это область, в которой имена целевых локальных переменных надежно известны компилятору при компиляции кода, что позволяет оптимизировать доступ для чтения и записи к этим именам.

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

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

Вызов locals() как части выражения генератора эквивалентен вызову его во вложенной функции генератора.

Изменено в Python 3.12: Поведение locals() в выражении-генератора было обновлено, как описано в PEP 709.

Изменено в Python 3.13: В предыдущих версиях, возможность доступа к изменениям, путем вызова locals() после вызова функции, выполнение кода зависело от реализации. В частности, в CPython такой код обычно работает ожидаемо, но иногда может давать сбой в оптимизированных областях, основанных на другом коде (включая отладчики и инструменты отслеживания выполнения кода), что может привести к сбросу общего моментального снимка в этой области. Теперь код всегда будет работать с независимым снимком локальных переменных в оптимизированных областях, и, следовательно, изменения никогда не будут видны при последующих вызовах locals(). Чтобы получить доступ к изменениям, внесенным в этих случаях, нужно передать явную ссылку на пространство имен соответствующей функции. В качестве альтернативы может иметь смысл обновить затронутый код, чтобы использовать API выполнения кода более высокого уровня, который возвращает результирующее пространство имен выполнения кода (например, |runpy.run_path()| при выполнении файлов Python с диска).

Пример попытки изменения переменных оптимизированной области видимости.

asd = 1

def func(a=1):
    b = 2
    c = a + b
    x = locals()
    print(x)

>>> func()
# В словаре нет глобальной переменной 'asd'
# {'c': 3, 'b': 2, 'a': 1}

Попробуем изменить переменную 'b' словаря locals()

def func(a=1):
    b = 2
    c = a + b
    x = locals()
    # изменяем переменную `b`    
    x['b'] = 5
    # снова делаем сложение
    c = a + b
    print(x)

>>> func()
# переменная словаря `b` изменилась, а сумма `c` - НЕТ
# {'a': 1, 'b': 5, 'c': 3}

Попробуем изменить переменную 'b' до сложения:

def func(a=1):
    b = 2
    x = locals()
    # изменяем переменную `b`    
    x['b'] = 5
    # снова делаем сложение
    c = a + b
    print(x)

>>> func()
# переменная словаря `b` изменилась, а суммы 
# `c` в словаре `locals()` вообще НЕТ.
# {'a': 1, 'b': 5}