Пространства имен в Python

Что такое пространство имён?

подробнее

Пространство имен — это система, которая гарантирует, что все имена в программе уникальны и могут быть использованы без конфликта. Это своего рода “словарь”, где ключи — это имена переменных, а значения — это сами объекты.

Какие есть пространства имен в Python?

подробнее
  • Built-in — встроенные имена (print, len, str и т.д.)
  • Global — имена на уровне модуля
  • Enclosing — имена во внешних функциях (при замыканиях)
  • Local — имена внутри функции

LEGB правило

подробнее

Python использует правило LEGB для разрешения имен переменных

Local (Локальное)

  • Имена, определенные внутри текущей функции
  • Создается при вызове функции и уничтожается при выходе из нее
def my_function():
    x = 10  # локальная переменная
    print(x)

Enclosing (Объемлющее)

  • Имена в локальных областях объемлющих функций (замыкания)
  • Актуально при вложенных функциях
def outer():
    x = 20  # enclosing переменная
    
    def inner():
        print(x)  # обращение к переменной из объемлющей области
    inner()

outer()  # выводит: 20

Global (Глобальное)

  • Имена на уровне модуля (вне всех функций)
  • Создается при импорте модуля
y = 30  # глобальная переменная

def func():
    print(y)  # обращение к глобальной переменной

func()  # выводит: 30

Built-in (Встроенное)

  • Имена встроенных функций и исключений (print, len, ValueError и т.д.)
  • Часть стандартной библиотеки Python
def func():
    print(len("hello"))  # len - встроенная функция

func()  # выводит: 5

Как работает разрешение имен?

Python ищет имя в порядке: Local → Enclosing → Global → Built-in

# Built-in: print, len
# Global:
x = "global"

def outer():
    # Enclosing:
    x = "enclosing"
    
    def inner():
        # Local:
        x = "local"
        print(x)  # выводит: local
    
    inner()
    print(x)      # выводит: enclosing

outer()
print(x)          # выводит: global

Работа с областями видимости (global, nonlocal)

подробнее

Ключевые слова:

  • global — указывает, что переменная принадлежит глобальной области
  • nonlocal — указывает, что переменная принадлежит объемлющей (enclosing) области
x = "global"

def outer():
    x = "enclosing"
    
    def inner():
        global x
        x = "modified global"
        print(x)  # выводит: modified global
    
    inner()
    print(x)      # выводит: enclosing (не изменилась)

outer()
print(x)          # выводит: modified global
def outer():
    x = "enclosing"
    
    def inner():
        nonlocal x
        x = "modified enclosing"
        print(x)  # выводит: modified enclosing
    
    inner()
    print(x)      # выводит: modified enclosing

outer()

Важные моменты:

  • LEGB применяется только для чтения переменных, не для их создания
  • Присваивание создает переменную в локальной области, если не указано иное
  • Функции создают новую локальную область при каждом вызове
  • Модули имеют глобальную область, которая существует всё время выполнения