Короткий ответ
Python по умолчанию считает переменную, которой присваивается значение внутри функции, локальной для этой функции; ключевое слово global явно говорит интерпретатору, что присваивание должно изменить переменную в глобальной области видимости модуля, а не создавать новую локальную.
Как это работает подробнее
Интерпретатор анализирует тело функции целиком перед выполнением: если переменной где-либо внутри функции присваивается значение (без global/nonlocal), она считается локальной во всей функции, даже в строчках до присваивания — это может привести к UnboundLocalError, если переменную с тем же именем сначала читают, а потом присваивают. global name отменяет это поведение для конкретного имени внутри функции.
Пример кода
example.py
counter = 0
def increment_broken():
counter += 1 # UnboundLocalError: присваивание делает counter локальным
def increment_fixed():
global counter
counter += 1
increment_fixed()
increment_fixed()
print(counter) # 2
try:
increment_broken()
except UnboundLocalError as e:
print("Ошибка:", e)Что использовать на практике
- Практика. Читать глобальную переменную внутри функции можно без
global— он нужен только для её изменения (присваивания нового значения) внутри функции. На практике частое изменение глобальных переменных черезglobalсчитается плохой практикой — предпочтительнее передавать данные через аргументы и возвращаемые значения или хранить состояние в объекте.
Подводные камни
- Риски. Пытаются изменить глобальную переменную внутри функции без
globalи неожиданно создают новую локальную переменную, из-за чего изменение "пропадает" за пределами функции. Также путаютglobal(для модульной области) сnonlocal(для области видимости объемлющей функции).