На PyCon US 2026 Руководящий совет Python рассказал о новых возможностях Python 3.15. Среди них — явные ленивые импорты (PEP 810): модули теперь можно загружать не при старте программы, а только в момент первого обращения. Я решил разобраться, как это работает, и измерить производительность в PyCharm.
В статье используется PyCharm. С 2022 года JetBrains не продаёт лицензии российским пользователям, поэтому без "танцев с бубном" получить полноценную поддержку не получится.
OpenIDE поддерживает не только Python, но и Java, Spring, Go, PHP, JavaScript и TypeScript! А полноценный DB-клиент, поддержка Docker и 300+ плагинов доступны абсолютно бесплатно в маркетплейсе.
Что такое явные ленивые импорты
PEP 810 вводит ключевое слово lazy для объявления отложенных импортов. Стандартный импорт выполняется сразу при запуске файла — ленивый откладывает загрузку модуля до первого обращения к его атрибутам.
Это сокращает время старта приложения и уменьшает потребление памяти. В большом CLI-инструменте или приложении с десятками библиотек разница ощутима.
Реализация построена на прокси-объектах в пространстве имён модуля — без изменений в базовых структурах данных интерпретатора. Это сохраняет существующие оптимизации CPython. Поиск и загрузка модуля откладываются вместе — это важно для файловых систем с высокой задержкой.
Для обратной совместимости PEP предусматривает глобальные управляющие флаги и переходную переменную.
Установка Python 3.15.0b1
На момент написания статьи Python 3.15.0b1 уже доступен. Проще всего установить его через uv или pyenv.
Убедитесь, что у вас последняя версия uv или pyenv, затем выполните одну из команд:
uv python install 3.15.0b1
pyenv install 3.15.0b1

После этого выберите новый интерпретатор в настройках проекта PyCharm и переустановите зависимости — большинство библиотек пока не имеют готового wheel для Python 3.15, поэтому часть пакетов будет собираться из исходников.
Профилирование: обычный импорт vs ленивый
В среде data science принято начинать каждый скрипт с import pandas as pd и import numpy as np — даже если они не нужны. Допустим, вы получили от коллеги такой файл:
import pandas as pd import matplotlib.pyplot as plt import numpy as np def main(): print("Initializing example data science project...") # Генерируем тестовые данные data = { 'x': np.linspace(0, 10, 100), 'y': np.sin(np.linspace(0, 10, 100)) + np.random.normal(0, 0.1, 100) } # Строим график plt.figure(figsize=(10, 6)) plt.plot(data['x'], data['y'], label='Sine Wave with Noise') plt.title('Sample Visualization') plt.xlabel('X-axis') plt.ylabel('Y-axis') plt.legend() # Сохраняем файл (неинтерактивный режим) plt.savefig('sine_wave.png') print("Project executed successfully. Plot saved as sine_wave.png.") if __name__ == "__main__": main()
PyCharm подсвечивает неиспользуемый pandas — убрать его легко. Но для эксперимента оставим его.
Чтобы наглядно увидеть профиль импортов, установите пакет tuna:
pip install tuna
Запустите профилирование через кастомный скрипт запуска:
python -X importtime main.py 2> import_log.txt; tuna import_log.txt
В браузере откроется граф импортов.

pandas занимает половину всего времени загрузки, хотя в этом скрипте не используется.
Теперь добавим lazy ко всем импортам:
lazy import pandas as pd lazy import matplotlib.pyplot as plt lazy import numpy as np

PyCharm пока не подсвечивает lazy — это новое ключевое слово, не вошедшее в релиз.
Снова запустим профилирование.

pandas исчез из графа. Суммарное время загрузки модулей сократилось заметно.
Если скрипт подключает много крупных библиотек, которые нужны лишь в некоторых ветках (например, в блоках if/else), ленивые импорты загрузят их только при реальном обращении.
Как ленивые импорты работают внутри
Когда модуль объявлен как lazy, вместо обычного import вызывается __lazy_import__. Создаётся прокси-объект types.LazyImportType, а имя модуля попадает в sys.lazy_modules вместо sys.modules. Подробнее — в разделе Lazy import mechanism PEP 810.
Когда прокси-объект используется впервые, CPython выполняет реальный импорт (reification): вызывает import, заменяет прокси настоящим модулем и убирает его из sys.lazy_modules.
Если при reification возникает ошибка, прокси остаётся. При следующем обращении попытка повторяется. В трейсбеке будут указаны оба места: где объявлен ленивый импорт и где произошло обращение. Подробнее — в разделе Reification PEP 810.
Исследуем в отладчике
Добавим точки остановки через pdb:
import pdb pdb.set_trace() lazy import pandas as pd lazy import matplotlib.pyplot as plt lazy import numpy as np pdb.set_trace() # ... остальной код
И ещё две точки — вокруг первого использования numpy и matplotlib:
# Генерируем данные data = { 'x': np.linspace(0, 10, 100), 'y': np.sin(np.linspace(0, 10, 100)) + np.random.normal(0, 0.1, 100) } pdb.set_trace() # Строим график plt.figure(figsize=(10, 6)) pdb.set_trace() # ...
Запускаем из консоли:
python main.py
PyCharm пока что не поддерживает Python 3.15, поэтому кнопки Run и Debug могут вести себя непредсказуемо с ленивыми импортами. Используйте консоль.
Первая точка остановки — до объявления импортов. Проверяем:
(Pdb) import sys (Pdb) sys.lazy_modules

Список пуст — ни pandas, ни numpy, ни matplotlib не загружены.
Вторая точка — после объявления ленивых импортов. Снова проверяем:
(Pdb) sys.lazy_modules

Все три модуля появились в sys.lazy_modules. Проверяем, есть ли pandas в sys.modules:
(Pdb) 'pandas' in sys.modules

False. То же самое — для numpy и matplotlib.
Третья точка — после первого использования numpy. Проверяем sys.lazy_modules:

numpy исчез из sys.lazy_modules. Теперь он в sys.modules — True.
pandas и matplotlib по-прежнему не загружены.
Четвёртая точка — после первого использования matplotlib:

matplotlib также перешёл из sys.lazy_modules в sys.modules.
pandas не используется нигде в скрипте — и так и остался незагруженным.

Уже сейчас OpenIDE позволяет разрабатывать проекты на Java, Spring, Python, Go, PHP, JavaScript и TypeScript! А полноценный DB-клиент, поддержка Docker и 300+ плагинов доступны абсолютно бесплатно в маркетплейсе. Пробуйте российскую IDE в деле и подписывайтесь на нас в Telegram или Max, чтобы не пропустить свежие обновления и полезные материалы.
