ПрограммированиеBackend разработчик

Что такое область видимости (scope) переменных в Python, как работает ключевое слово `global`? Приведите пример из практики, где неправильное понимание области видимости приводит к ошибкам.

Проходите собеседования с ИИ помощником Hintsage

Ответ.

Область видимости (scope) переменной — это контекст, в котором она доступна. В Python есть 4 основных области видимости, которые можно запомнить по принципу LEGB:

  • Local (локальная) — внутри функции.
  • Enclosing (замыкающая) — внутри внешних функций для вложенных функций.
  • Global (глобальная) — на уровне модуля.
  • Built-in (встроенные имена Python).

Ключевое слово 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.