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

Расскажите особенности организации пространства имен (namespaces) и модулей в Python. Как работает импорты, и как избежать конфликтов имен при большом проекте?

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

Ответ.

В Python пространство имён (namespace) — это словарь, где связываются имена и объекты. Уровни пространств имён: локальное, глобальное, встроенное. Модули — отдельные пространства для организации кода. При импорте Python создаёт новое пространство имен для каждого модуля.

Работа импорта

  • import module — импортирует модуль и доступ к объектам через module.name.
  • from module import name — импортирует объект из модуля прямо в текущее пространство (риск конфликтов имен).
  • as — позволяет задать псевдоним.

Чтобы избежать конфликтов имен:

  • Используйте явный импорт модулей (import mymodule), а не звёздочку (from... import *).
  • Организовывайте проект с помощью пакетов (директорий с __init__.py).
  • Используйте уникальные, говорящие имена;
  • Применяйте псевдонимы (import module as m).

Пример структуры

project/
  package/
    __init__.py
    module1.py
    module2.py
import package.module1 from package.module2 import function as fn

Вопрос с подвохом.

Вопрос: Чем отличается импортирование модуля дважды? Будет ли выполнен весь код модуля повторно?

Ответ: Нет. При первом импорте модуль исполняется и результат кешируется в sys.modules. Повторный импорт возвращает уже загружённый объект модуля, его код не выполняется повторно.

# module.py print('Hello!') # main.py import module # выведет Hello! import module # ничего не выведется

Примеры реальных ошибок из-за незнания тонкостей темы.


История

Разработчики использовали from settings import * в нескольких модулях, в результате при изменении настроек неожиданно "перезаписывались" локальные переменные, вызвав трудновыявляемые баги.

История

В крупном проекте разные команды создали модули с одинаковыми именами (например, utils.py). На этапе интеграции модули с "одинаковым" именем "подменяли" друг друга, приводя к неожиданному поведению и сложным багам.

История

В одной из библиотек пытались "горячо переимпортировать" модуль с новыми настройками через importlib.reload. Не учли, что уже импортированные другие модули сохранили старые ссылки на объекты, из-за чего изменения не применялись во всех частях приложения.