← Назад к вопросам
Что хранится в пространстве имен в Python?
1.7 Middle🔥 201 комментариев
#DevOps и инфраструктура#Django
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Пространство имён в Python
Пространство имён (namespace) — это словарь, который сопоставляет имена объектам. Всё в Python является объектом, и пространство имён позволяет интерпретатору находить и управлять этими объектами. Это критически важная концепция для понимания области видимости и разрешения имён.
Типы пространств имён
В Python существует четыре основных типа пространств имён, каждое со своей областью видимости:
1. Встроенное пространство имён (Built-in)
# Встроенное пространство имён содержит встроенные функции и типы
import builtins
print(dir(builtins)) # Выведет все встроенные имена
# Примеры встроенных функций
print(len) # <built-in function len>
print(int) # <class int>
print(str) # <class str>
print(Exception) # <class Exception>
# Можем просмотреть все встроенные имена
built_ins = [name for name in dir(builtins) if not name.startswith(_)]
print(f"Встроенных имён: {len(built_ins)}")
2. Глобальное пространство имён (Global)
# Глобальное пространство имён модуля
x = 10 # Глобальная переменная
def global_namespace_example():
# Функция видит глобальные переменные
print(f"x из глобального пространства: {x}")
# Просмотр глобального пространства имён
print(f"Глобальные переменные: {globals()}")
print(f"Ключи: {list(globals().keys())}")
global_namespace_example()
# Используем global для изменения глобальной переменной
def modify_global():
global x
x = 20
print(f"Изменённое x: {x}")
modify_global()
print(f"x теперь: {x}")
3. Локальное пространство имён (Local)
def function_with_local_namespace():
local_var = 42 # Локальная переменная
nested_var = "text" # Ещё одна локальная переменная
print(f"Локальные переменные: {locals()}")
def nested_function():
nested_local = 100
print(f"Локальные переменные вложенной функции: {locals()}")
nested_function()
function_with_local_namespace()
# Локальные переменные не видны вне функции
try:
print(local_var)
except NameError:
print("NameError: local_var не определена на глобальном уровне")
4. Замыкание (Enclosing)
def outer():
enclosing_var = "I am enclosing" # Переменная промежуточного уровня
def inner():
# Доступ к переменной из enclosing scope
print(f"Вложенная функция видит: {enclosing_var}")
print(f"Локальные переменные: {locals()}")
inner()
return inner
inner_func = outer()
inner_func() # Замыкание сохраняет доступ к enclosing_var
LEGB правило разрешения имён
Python использует правило LEGB для поиска переменных:
x = "global" # Global
def outer():
x = "enclosing" # Enclosing
def inner():
x = "local" # Local
print(f"x = {x}") # Local
def inner2():
print(f"x = {x}") # Enclosing
inner() # Выведет: x = local
inner2() # Выведет: x = enclosing
print(f"x = {x}") # Global: x = global
outer()
# Пример с nonlocal
def outer2():
count = 0
def increment():
nonlocal count # Модифицирует переменную enclosing scope
count += 1
return count
print(increment()) # 1
print(increment()) # 2
print(increment()) # 3
outer2()
Пространства имён в классах
class MyClass:
class_var = 10 # Переменная класса
def __init__(self, name):
self.instance_var = name # Переменная экземпляра
def method(self):
method_local = 42
print(f"Локальное пространство метода: {locals()}")
# Просмотр пространств имён класса
print(f"Пространство имён класса: {MyClass.__dict__}")
print(f"Ключи: {list(MyClass.__dict__.keys())}")
# Просмотр пространства имён экземпляра
obj = MyClass("Alice")
print(f"Пространство имён экземпляра: {obj.__dict__}")
print(f"Ключи: {list(obj.__dict__.keys())}")
obj.method()
Модули как пространства имён
# Каждый модуль имеет своё пространство имён
import math
import os
# Просмотр пространства имён модуля
print(f"Модуль math содержит: {dir(math)}")
print(f"Функции math: {[name for name in dir(math) if not name.startswith(_)]}")
# Доступ к переменным модуля через __dict__
print(f"Пространство имён модуля: {math.__dict__.keys()}")
# Импорт конкретных имён
from math import pi, sqrt
print(f"pi = {pi}")
print(f"sqrt(16) = {sqrt(16)}")
Динамическое управление пространствами имён
# Используем globals() и locals() для динамического доступа
def dynamic_namespace():
local_var = "local"
# Просмотр переменной через locals()
print(f"Переменная есть в locals: {local_var in locals()}")
# Динамическое создание переменной
locals()["dynamic_var"] = "dynamically created"
# Внимание: изменение locals() обычно не работает как ожидается
print(f"dynamic_var определена: {locals()}")
dynamic_namespace()
# Более надёжный способ - использовать exec()
def exec_example():
namespace = {}
exec("x = 10; y = 20; z = x + y", namespace)
print(f"Результат: {namespace[z]}")
exec_example()
# Использование getattr/setattr для динамического доступа
class Config:
pass
config = Config()
setattr(config, debug, True)
setattr(config, timeout, 30)
print(f"debug = {getattr(config, debug)}")
print(f"timeout = {getattr(config, timeout)}")
print(f"Пространство имён объекта: {config.__dict__}")
Практические примеры
# Пример 1: Счётчик с замыканием
def make_counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
counter = make_counter()
print(counter()) # 1
print(counter()) # 2
print(counter()) # 3
# Пример 2: Кэширование через замыкание
def cache_decorator():
cache = {} # Находится в enclosing namespace
def decorator(func):
def wrapper(n):
if n not in cache:
cache[n] = func(n)
return cache[n]
return wrapper
return decorator
make_cache = cache_decorator()
@make_cache()
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
Важные правила
- Встроенные имена всегда доступны, но могут быть затенены локальными
- Глобальные имена видны во всём модуле
- Локальные имена существуют только в функции
- Enclosing имена видны во вложенных функциях (замыкания)
- LEGB правило определяет порядок поиска
Понимание пространств имён критично для работы с переменными, функциями и модулями в Python.