globals() в Python: словарь глобальных имен модуля
Встроенная функция globals() в Python возвращает словарь с глобальными именами текущего модуля: переменными, функциями, классами и импортированными модулями. Из статьи вы узнаете, как читать и менять глобальные переменные через этот словарь, чем globals() отличается от инструкции global и функции locals(), и в каких задачах ее применение оправдано.

Содержание статьи
Что возвращает globals()
Каждый модуль Python хранит свои глобальные имена в словаре, который называют пространством имен модуля. Ключи в нем - имена в виде строк, значения - сами объекты. Функция globals() аргументов не принимает и возвращает ссылку именно на этот словарь, а не на копию.
import math
rate = 0.13
def tax(amount):
return amount * rate
names = [k for k in globals() if not k.startswith("__")]
print(names) # ['math', 'rate', 'tax']Кроме созданных вами имен, в словаре всегда есть служебные записи с двойным подчеркиванием: __name__ (имя модуля, при прямом запуске "__main__"), __doc__, __builtins__ и другие. В интерактивных средах вроде IPython или Jupyter добавляются их собственные переменные, например история ввода In и Out, поэтому вывод там длиннее.
Глобальными считаются переменные, функции и классы, объявленные на верхнем уровне файла, вне любых def и class. Переменные внутри функций в этот словарь не попадают.
Чтение и изменение переменных через словарь
Раз globals() возвращает живой словарь модуля, через него можно получить значение по имени, записанному в строке, и изменить его. Изменение сразу видно в обычном коде.
age = 23
globals()["age"] = 25
print("Возраст:", age) # Возраст: 25
globals()["city"] = "Казань" # новая глобальная переменная
print(city) # КазаньВторая часть примера работает, но редактор кода подчеркнет city как неизвестное имя: статический анализ не видит переменных, созданных динамически. Это главный аргумент против такого приема в рабочем коде.
Более полезный сценарий - вызвать функцию по ее имени, полученному извне, например из командной строки или конфигурационного файла:
def start():
return "Запуск"
def stop():
return "Остановка"
command = "stop"
handler = globals().get(command)
if callable(handler):
print(handler()) # ОстановкаНадежнее завести явный словарь допустимых команд: commands = {"start": start, "stop": stop}. Тогда пользователь не сможет вызвать произвольную функцию модуля, а список команд виден в одном месте.
Отличие от инструкции global
Внутри функции присваивание создает локальную переменную. Чтобы изменить глобальную, Python предлагает инструкцию global. Она объявляет, что имя относится к модулю, и дальше с переменной работают как обычно.
counter = 0
def inc_global():
global counter
counter += 1
def inc_dict():
globals()["counter"] += 1
inc_global()
inc_dict()
print(counter) # 2Результат одинаковый, но global читается проще, проверяется линтерами и не требует писать имя строкой. globals() нужна, когда имя переменной заранее неизвестно и вычисляется во время работы программы. Для переменных внешней функции, а не модуля, используется nonlocal, этот случай разобран в статье про замыкания.
Учтите, что globals() внутри функции возвращает глобальные имена того модуля, где функция объявлена, а не того, откуда ее вызвали. Функция из импортированного модуля через globals() видит только свой модуль.
globals(), locals() и vars()
У globals() есть две родственные функции. Их легко перепутать, поэтому сравним их в таблице.
| Функция | Что возвращает | Изменение словаря |
|---|---|---|
globals() | Имена модуля | Меняет глобальные переменные |
locals() | Имена текущей области: внутри функции локальные, на уровне модуля те же, что globals() | Внутри функции не меняет реальные переменные |
vars() | Без аргумента как locals(), с аргументом атрибут __dict__ объекта | Для объекта меняет его атрибуты |
x = "глобальная"
def show():
y = "локальная"
print(locals()) # {'y': 'локальная'}
print("x" in globals()) # True
print("y" in globals()) # False
show()Для просмотра доступных имен в виде списка подходит функция dir(): без аргументов она возвращает отсортированный список имен текущей области.
Пространство имен для exec и eval
Функции exec() и eval() принимают словарь глобальных имен вторым аргументом. Если передать globals(), выполняемый код увидит и сможет изменить переменные модуля. Если передать отдельный словарь, код работает в изолированном пространстве.
sandbox = {"price": 100}
exec("total = price * 2", sandbox)
print(sandbox["total"]) # 200
print("total" in globals()) # FalseТакая изоляция защищает переменные программы от случайной перезаписи, но не делает выполнение чужого кода безопасным: через встроенные функции он все равно получит доступ к системе. Подробнее о рисках в статье про exec.
Когда применять globals()
В прикладном коде функция нужна редко. Оправданные случаи:
- отладка и интроспекция: вывести, какие имена определены в модуле;
- передача пространства имен в exec() или eval();
- регистрация или поиск объектов по имени в небольших скриптах и плагинах.
Для хранения настроек и общего состояния лучше подходят явные структуры: словарь, класс с атрибутами или отдельный модуль config. Код без неявных изменений глобальных имен проще тестировать и читать. Описание функции есть в документации Python.
Частые вопросы
Короткие ответы на вопросы о globals().
Возвращает ли globals() копию словаря?
Нет, это ссылка на настоящий словарь модуля. Любое изменение в нем сразу меняет глобальные переменные, а новые переменные, объявленные позже, появятся в уже полученном словаре.
Как удалить глобальную переменную через globals()?
Так же, как ключ словаря: del globals()["name"] или globals().pop("name", None). Обычная инструкция del name на уровне модуля дает тот же результат.
Можно ли получить глобальные переменные другого модуля?
Да, через vars(module) или атрибут module.__dict__ после импорта. Это тот же словарь, который вернула бы globals() внутри того модуля.
Почему в Jupyter globals() выводит так много лишнего?
Среда хранит в глобальной области историю ввода и вывода (In, Out, _i1 и подобные) и служебные функции. В обычном скрипте .py словарь заметно короче.