Что происходит, когда модуль импортируется с разных точек входа в программу?

Когда модуль импортируется повторно из разных мест в программе, Python выполняет следующие действия:
  1. Проверяет `sys.modules`: Сначала Python смотрит в словарь `sys.modules`, который кеширует уже импортированные модули.
  2. Если модуль уже импортирован: Если модуль найден в `sys.modules`, он просто возвращается. Код модуля не выполняется повторно. Это позволяет избежать дублирования кода и возможных проблем с состоянием.
  3. Если модуль не импортирован: Если модуля нет в `sys.modules`, Python выполняет поиск, загрузку и выполнение кода модуля (только один раз). Затем модуль добавляется в `sys.modules`.
Таким образом, импорт модуля происходит только один раз за время выполнения программы (в пределах одного интерпретатора). Последующие импорты этого же модуля просто возвращают ссылку на уже существующий объект модуля.

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

Процесс импорта:

  1. Когда Python встречает оператор `import`, он сначала проверяет, был ли модуль уже импортирован ранее в течение текущего сеанса работы интерпретатора. Эта информация хранится в словаре `sys.modules`.
  2. Если модуль уже есть в `sys.modules`, Python просто использует уже загруженный объект модуля. Никакой повторной загрузки и инициализации не происходит. Это означает, что все переменные, функции и классы, определенные в модуле, будут общими для всех частей программы, которые его импортируют.
  3. Если модуля нет в `sys.modules`, Python выполняет следующие шаги:
    • Находит файл модуля (обычно `.py` файл) используя `sys.path` (список директорий, где Python ищет модули).
    • Читает и компилирует код модуля.
    • Создает новый объект модуля.
    • Исполняет код модуля (выполняются все верхнеуровневые операторы, определяются функции, классы, присваиваются значения переменным).
    • Добавляет объект модуля в `sys.modules`.

Ключевые моменты:

  • Единожды загружен: Модуль загружается и исполняется только один раз за сеанс работы интерпретатора, независимо от того, сколько раз он импортируется.
  • Состояние модуля: Любые изменения, внесенные в состояние модуля (например, изменение значения глобальной переменной) одной частью программы, будут видны всем остальным частям программы, которые импортируют этот модуль.
  • `sys.modules`: Этот словарь является ключевым для понимания механизма импорта. Вы можете использовать его для проверки, был ли модуль уже загружен, и даже для ручного манипулирования импортом (хотя это обычно не рекомендуется).
  • Побочные эффекты: Поскольку код модуля выполняется только один раз, любые побочные эффекты, возникающие во время импорта (например, создание файлов, подключение к базам данных), также произойдут только один раз.

Пример:

    
    # модуль my_module.py
    print("Модуль my_module загружен")
    x = 10

    # script1.py
    import my_module
    print("x в script1:", my_module.x)
    my_module.x = 20

    # script2.py
    import my_module
    print("x в script2:", my_module.x)

    # Вывод:
    # Модуль my_module загружен
    # x в script1: 10
    # x в script2: 20
    
  

В этом примере, "Модуль my_module загружен" будет напечатано только один раз. Изменение значения `my_module.x` в `script1.py` отразится на `script2.py`.

0