Что такое пространство имен (namespace) в Python и зачем оно нужно?

Ответ

Пространство имен (namespace) в Python — это система, которая обеспечивает уникальность имен объектов (переменных, функций, классов). Ее основная задача — избежать конфликтов имен, когда разные объекты случайно получают одинаковые идентификаторы.

Технически, это словарь, где ключами являются имена, а значениями — сами объекты.

Виды пространств имен

Python использует несколько пространств имен, и поиск имени идет в следующем порядке (правило LEGB):

  1. L (Local) — Локальное: имена внутри текущей функции.
  2. E (Enclosing) — Замыкающее: имена во внешних функциях (для вложенных функций).
  3. G (Global) — Глобальное: имена на уровне модуля.
  4. B (Built-in) — Встроенное: предопределенные имена в Python (print, len, str и т.д.).

Пример

x = "global_x"  # Глобальное пространство имен (G)

def outer_func():
    y = "enclosing_y"  # Замыкающее пространство имен (E)

    def inner_func():
        z = "local_z"  # Локальное пространство имен (L)
        print(z)  # Найдено в L
        print(y)  # Найдено в E
        print(x)  # Найдено в G
        print(len(x)) # len найдено в B (Built-in)

    inner_func()

outer_func()

Каждый модуль в Python создает свое собственное глобальное пространство имен, что позволяет использовать одинаковые имена функций или переменных в разных файлах без конфликтов.

Ответ 18+ 🔞

Слушай, а вот эта вся хуйня с пространствами имён в Python — это, блядь, такая система, чтобы твои переменные и функции не подрались между собой, как пьяные мужики у ларька. Представь словарь, где ключ — это имя, а значение — сам объект. Всё просто, как три копейки.

А теперь, внимание, ёпта, правило LEGB — это святое! Интерпретатор ищет имена именно в таком порядке, иначе будет пиздец:

  1. L (Local) — Лукошко, блядь. Всё, что ты объявил внутри функции, там и валяется.
  2. E (Enclosing) — Замыкающее, сука. Если функция вложенная, то это всё, что лежит в родительской функции. Как будто заглянул в карман к соседу.
  3. G (Global) — Глобальное, на уровне всего модуля. Как общий холодильник на работе — кто что положил, тот то и взял.
  4. B (Built-in) — Встроенное, мать его. Это типа print, len — они уже тут, их не надо тащить, они как родные.

Вот смотри, живой пример, блядь:

x = "global_x"  # Засунули в общий холодильник (G)

def outer_func():
    y = "enclosing_y"  # Спрятали в карман куртки (E)

    def inner_func():
        z = "local_z"  # Держим в кулаке (L)
        print(z)  # Ну тут понятно, из кулака достали
        print(y)  # Полезли в карман куртки — нашли!
        print(x)  # Побежали к общему холодильнику — вот он!
        print(len(x)) # А это len — оно вообще из коробки (B), всегда под рукой.

    inner_func()

outer_func()

И главная фишка, блядь, в том, что каждый файл-модуль — это свой отдельный мир со своим глобальным пространством. Можно в десяти файлах переменную i назвать и нихуя не будет, они друг про друга не знают. Красота, ёпта!