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}