Область видимости (scope) переменной — это контекст, в котором она доступна. В Python есть 4 основных области видимости, которые можно запомнить по принципу LEGB:
Ключевое слово global позволяет изменять переменную, объявленную на глобальном уровне, изнутри функции.
def foo(): global my_var my_var = 10 # изменяет глобальную переменную
Без global внутри функции переменная считается локальной, даже если такое имя есть во внешней области.
"Что выведет следующий код?"
x = 10 def func(): x = 20 func() print(x)
Ответ:
Выведет 10, потому что внутри функции создаётся новая локальная переменная x, глобальная не изменяется.
История
В обработчике команд бота хотели хранить глобальный счётчик, но забыли про global:
counter = 0 def increment(): counter += 1 # UnboundLocalError: local variable 'counter' referenced before assignment
Ошибка из-за того, что интерпретатор считает, что counter — локальная переменная (так как по ходу функции идёт её присваивание), а не глобальная.
История
Во вложенных функциях забыли, что без ключевого слова nonlocal скрытая переменная создаёт локальный scope:
def outer(): x = 0 def inner(): x += 1 # UnboundLocalError, x считается локальной в inner
Правильно:
def outer(): x = 0 def inner(): nonlocal x x += 1
История
Писали однострочник:
x = 5 y = (lambda: (x := x + 1))() # SyntaxError в Python < 3.8, или UnboundLocalError позже
Забыли различие scope для выражения и lambda. Не все конструкции поддерживают assignment внутри lambda, в зависимости от версии Python.