[{"data":1,"prerenderedAt":142},["ShallowReactive",2],{"$fBBQ5ulyG5jVWbIBJe3r8F-kTKQKf1scMJiu0B6qzX5k":3,"$f7AVZHmPutZ23_8XKkLbDtEszKCuiY3yPjIDp9eRXGag":5,"$fxHITlpiVTOaYLfyPzZvqCc2jzYLb8tIZMkBy0C1QmUs":7,"$fHa860e1fnpCnRO4Gi5c9pEVMKDBAmZ2IgWYt4zRqQqg":118},{"data":4},[],{"data":6},[],{"data":8,"meta":114},[9],{"id":10,"documentId":11,"title":12,"seo_title":13,"summary":14,"seo_description":15,"slug":16,"published_date":17,"body":18,"content":19,"createdAt":35,"updatedAt":36,"publishedAt":37,"blogauthor":38,"cover":60,"categories":103},355,"szopwdkqo292rl7vrla29h52","Ленивые импорты в Python 3.15: как PEP 810 ускоряет старт приложений","Ленивые импорты в Python 3.15: PEP 810 на практике","В Python 3.15 появились явные ленивые импорты. Разбираем PEP 810, сравниваем профили обычного и ленивого импорта pandas, numpy и matplotlib и смотрим механику в pdb.","Как работает ключевое слово lazy из PEP 810 в Python 3.15: установка 3.15.0b1, профилирование импортов через tuna и проверка sys.lazy_modules в отладчике.","lenivye-importy-v-python-3-15-kak-pep-810-uskoryaet-start-prilozhenij","2026-07-07","На PyCon US 2026 Руководящий совет Python рассказал о новых возможностях Python 3.15. Среди них — явные ленивые импорты ([PEP 810](https:\u002F\u002Fpeps.python.org\u002Fpep-0810\u002F)): модули теперь можно загружать не при старте программы, а только в момент первого обращения. Я решил разобраться, как это работает, и измерить производительность в PyCharm.\n\n---\n\n> В статье используется PyCharm. С 2022 года JetBrains не продаёт лицензии российским пользователям, поэтому без \"танцев с бубном\" получить полноценную поддержку не получится.\n>\n> [OpenIDE](https:\u002F\u002Fopenide.ru\u002F) поддерживает не только Python, но и Java, Spring, Go, PHP, JavaScript и TypeScript! А полноценный DB-клиент, поддержка Docker и 300+ плагинов доступны абсолютно бесплатно в [маркетплейсе](https:\u002F\u002Fmarketplace.openide.ru\u002F).\n\n\u003Ch3 id=\"chto-takoe-yavnye-lenivye-importy\">Что такое явные ленивые импорты\u003C\u002Fh3>\n\n[PEP 810](https:\u002F\u002Fpeps.python.org\u002Fpep-0810\u002F) вводит ключевое слово `lazy` для объявления отложенных импортов. Стандартный импорт выполняется сразу при запуске файла — ленивый откладывает загрузку модуля до первого обращения к его атрибутам.\n\nЭто сокращает время старта приложения и уменьшает потребление памяти. В большом CLI-инструменте или приложении с десятками библиотек разница ощутима.\n\nРеализация построена на прокси-объектах в пространстве имён модуля — без изменений в базовых структурах данных интерпретатора. Это сохраняет существующие оптимизации CPython. Поиск и загрузка модуля откладываются вместе — это важно для файловых систем с высокой задержкой.\n\nДля обратной совместимости PEP предусматривает глобальные управляющие флаги и переходную переменную.\n\n---\n\n\u003Ch3 id=\"ustanovka-python-3-15-0b1\">Установка Python 3.15.0b1\u003C\u002Fh3>\n\nНа момент написания статьи Python 3.15.0b1 уже доступен. Проще всего установить его через `uv` или `pyenv`.\n\nУбедитесь, что у вас последняя версия `uv` или `pyenv`, затем выполните одну из команд:\n\n```bash\nuv python install 3.15.0b1\n```\n\n```bash\npyenv install 3.15.0b1\n```\n\n![Установка Python 3.15 через uv или pyenv]({{strapiUrl}}\u002Fuploads\u002F15ce8a82d89974af8d4e0b535a288ff3_a712d58f68.webp)\n\nПосле этого выберите новый интерпретатор в настройках проекта PyCharm и переустановите зависимости — большинство библиотек пока не имеют готового wheel для Python 3.15, поэтому часть пакетов будет собираться из исходников.\n\n---\n\n\u003Ch3 id=\"profilirovanie-obychnyj-import-vs-lenivyj\">Профилирование: обычный импорт vs ленивый\u003C\u002Fh3>\n\nВ среде data science принято начинать каждый скрипт с `import pandas as pd` и `import numpy as np` — даже если они не нужны. Допустим, вы получили от коллеги такой файл:\n\n```python\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport numpy as np\n\ndef main():\n    print(\"Initializing example data science project...\")\n    \n    # Генерируем тестовые данные\n    data = {\n        'x': np.linspace(0, 10, 100),\n        'y': np.sin(np.linspace(0, 10, 100)) + np.random.normal(0, 0.1, 100)\n    }\n    \n    # Строим график\n    plt.figure(figsize=(10, 6))\n    plt.plot(data['x'], data['y'], label='Sine Wave with Noise')\n    plt.title('Sample Visualization')\n    plt.xlabel('X-axis')\n    plt.ylabel('Y-axis')\n    plt.legend()\n    \n    # Сохраняем файл (неинтерактивный режим)\n    plt.savefig('sine_wave.png')\n    print(\"Project executed successfully. Plot saved as sine_wave.png.\")\n\nif __name__ == \"__main__\":\n    main()\n```\n\nPyCharm подсвечивает неиспользуемый `pandas` — убрать его легко. Но для эксперимента оставим его.\n\nЧтобы наглядно увидеть профиль импортов, установите пакет [tuna](https:\u002F\u002Fpypi.org\u002Fproject\u002Ftuna\u002F):\n\n```bash\npip install tuna\n```\n\nЗапустите профилирование через кастомный скрипт запуска:\n\n```bash\npython -X importtime main.py 2> import_log.txt; tuna import_log.txt\n```\n\nВ браузере откроется граф импортов.\n\n![Граф импортов с обычными импортами — pandas занимает половину времени загрузки]({{strapiUrl}}\u002Fuploads\u002F0d871565b8dc3be1c5fa988125339e61_c1b4cb2f82.webp)\n\n`pandas` занимает половину всего времени загрузки, хотя в этом скрипте не используется.\n\nТеперь добавим `lazy` ко всем импортам:\n\n```python\nlazy import pandas as pd\nlazy import matplotlib.pyplot as plt\nlazy import numpy as np\n```\n\n![Код с ленивыми импортами — PyCharm пока не выделяет новый синтаксис]({{strapiUrl}}\u002Fuploads\u002F19c40ffeed2e72484e0c1532ea66035e_fc62216911.webp)\n\nPyCharm пока не подсвечивает `lazy` — это новое ключевое слово, не вошедшее в релиз.\n\nСнова запустим профилирование.\n\n![Граф импортов после применения lazy — pandas исчез из дерева загрузки]({{strapiUrl}}\u002Fuploads\u002Ff57583271528686d912a66525053bea5_6cb1e4da4e.webp)\n\n`pandas` исчез из графа. Суммарное время загрузки модулей сократилось заметно.\n\nЕсли скрипт подключает много крупных библиотек, которые нужны лишь в некоторых ветках (например, в блоках `if`\u002F`else`), ленивые импорты загрузят их только при реальном обращении.\n\n---\n\n\u003Ch3 id=\"kak-lenivye-importy-rabotayut-vnutri\">Как ленивые импорты работают внутри\u003C\u002Fh3>\n\nКогда модуль объявлен как `lazy`, вместо обычного `import` вызывается `__lazy_import__`. Создаётся прокси-объект `types.LazyImportType`, а имя модуля попадает в `sys.lazy_modules` вместо `sys.modules`. Подробнее — в разделе [Lazy import mechanism](https:\u002F\u002Fpeps.python.org\u002Fpep-0810\u002F#lazy-import-mechanism) PEP 810.\n\nКогда прокси-объект используется впервые, CPython выполняет реальный импорт (reification): вызывает `import`, заменяет прокси настоящим модулем и убирает его из `sys.lazy_modules`.\n\nЕсли при reification возникает ошибка, прокси остаётся. При следующем обращении попытка повторяется. В трейсбеке будут указаны оба места: где объявлен ленивый импорт и где произошло обращение. Подробнее — в разделе [Reification](https:\u002F\u002Fpeps.python.org\u002Fpep-0810\u002F#reification) PEP 810.\n\n#### Исследуем в отладчике\n\nДобавим точки остановки через `pdb`:\n\n```python\nimport pdb\npdb.set_trace()\nlazy import pandas as pd\nlazy import matplotlib.pyplot as plt\nlazy import numpy as np\npdb.set_trace()\n# ... остальной код\n```\n\nИ ещё две точки — вокруг первого использования numpy и matplotlib:\n\n```python\n    # Генерируем данные\n    data = {\n        'x': np.linspace(0, 10, 100),\n        'y': np.sin(np.linspace(0, 10, 100)) + np.random.normal(0, 0.1, 100)\n    }\n    pdb.set_trace()\n    \n    # Строим график\n    plt.figure(figsize=(10, 6))\n    pdb.set_trace()\n    # ...\n```\n\nЗапускаем из консоли:\n\n```bash\npython main.py\n```\n\n> PyCharm пока что не поддерживает Python 3.15, поэтому кнопки Run и Debug могут вести себя непредсказуемо с ленивыми импортами. Используйте консоль.\n\n**Первая точка остановки** — до объявления импортов. Проверяем:\n\n```python\n(Pdb) import sys\n(Pdb) sys.lazy_modules\n```\n\n![sys.lazy_modules пуст до объявления импортов]({{strapiUrl}}\u002Fuploads\u002F05a756b12f4f1d4b0420e7ec4dd85c94_579b478e75.webp)\n\nСписок пуст — ни pandas, ни numpy, ни matplotlib не загружены.\n\n**Вторая точка** — после объявления ленивых импортов. Снова проверяем:\n\n```python\n(Pdb) sys.lazy_modules\n```\n\n![sys.lazy_modules содержит pandas, numpy, matplotlib]({{strapiUrl}}\u002Fuploads\u002F6a4d9c2b0907e272e158a31a0be09ea4_a3f9da3001.webp)\n\nВсе три модуля появились в `sys.lazy_modules`. Проверяем, есть ли pandas в `sys.modules`:\n\n```python\n(Pdb) 'pandas' in sys.modules\n```\n\n![pandas в sys.modules — False]({{strapiUrl}}\u002Fuploads\u002Fff0f9cfb6aaa954d762d226b68a3ba9f_a99781e907.webp)\n\n`False`. То же самое — для numpy и matplotlib.\n\n**Третья точка** — после первого использования numpy. Проверяем `sys.lazy_modules`:\n\n![numpy удалён из sys.lazy_modules после первого использования]({{strapiUrl}}\u002Fuploads\u002Fa793477b6557aa2a4acd268cfd066a85_fb80959842.webp)\n\nnumpy исчез из `sys.lazy_modules`. Теперь он в `sys.modules` — `True`.\n\npandas и matplotlib по-прежнему не загружены.\n\n**Четвёртая точка** — после первого использования matplotlib:\n\n![matplotlib удалён из sys.lazy_modules]({{strapiUrl}}\u002Fuploads\u002F8071407abf88ea0796748286a141a73d_dd5ae31fcb.webp)\n\nmatplotlib также перешёл из `sys.lazy_modules` в `sys.modules`.\n\npandas не используется нигде в скрипте — и так и остался незагруженным.\n\n![]({{strapiUrl}}\u002Fuploads\u002Fc56b26087a188121b23a62999c07d439_b386c8935c.webp)\n\nУже сейчас [OpenIDE](https:\u002F\u002Fopenide.ru\u002F) позволяет разрабатывать проекты на Java, Spring, Python, Go, PHP, JavaScript и TypeScript! А полноценный DB-клиент, поддержка Docker и 300+ плагинов доступны абсолютно бесплатно в [маркетплейсе](https:\u002F\u002Fmarketplace.openide.ru\u002F). Пробуйте российскую IDE в деле и подписывайтесь на нас в [Telegram](https:\u002F\u002Ft.me\u002Fopenide_official) или [Max](https:\u002F\u002Fmax.ru\u002Fopenide), чтобы не пропустить свежие обновления и полезные материалы.\n\n---\n\n_Впервые опубликовано на [Хабре](https:\u002F\u002Fhabr.com\u002Fru\u002Fcompanies\u002Fhaulmont\u002Farticles\u002F1055958\u002F)._\n",[20],{"title":21,"links":22},"Содержание",[23,26,29,32],{"label":24,"href":25},"Что такое явные ленивые импорты","#chto-takoe-yavnye-lenivye-importy",{"label":27,"href":28},"Установка Python 3.15.0b1","#ustanovka-python-3-15-0b1",{"label":30,"href":31},"Профилирование: обычный импорт vs ленивый","#profilirovanie-obychnyj-import-vs-lenivyj",{"label":33,"href":34},"Как ленивые импорты работают внутри","#kak-lenivye-importy-rabotayut-vnutri","2026-11-12T11:25:54.484Z","2026-11-13T11:49:19.897Z","2026-11-13T11:49:19.957Z",{"id":39,"documentId":40,"firstname":41,"lastname":42,"createdAt":43,"updatedAt":44,"publishedAt":45,"slug":46,"photo":47},40,"yuewij1jc3qoxmkvsh2mpeny","Георгий","Власов","2026-02-17T11:40:25.168Z","2026-11-13T11:49:25.324Z","2026-11-13T11:49:25.371Z","georgij-vlasov",{"id":48,"documentId":49,"name":50,"alternativeText":51,"caption":51,"width":52,"height":52,"formats":51,"hash":53,"ext":54,"mime":55,"size":56,"url":57,"previewUrl":51,"provider":58,"provider_metadata":51,"createdAt":59,"updatedAt":59,"publishedAt":59,"focalPoint":51},1359,"jt1gpp4kqcyzwuwfhzj1c1vc","Gosha_ab88bd0ec5.webp",null,96,"Gosha_ab88bd0ec5_972867885d",".webp","image\u002Fwebp",2.14,"\u002Fuploads\u002FGosha_ab88bd0ec5_972867885d.webp","local","2026-11-13T11:47:15.450Z",{"id":61,"documentId":62,"name":63,"alternativeText":51,"caption":51,"width":64,"height":65,"formats":66,"hash":99,"ext":54,"mime":55,"size":100,"url":101,"previewUrl":51,"provider":58,"provider_metadata":51,"createdAt":102,"updatedAt":102,"publishedAt":102,"focalPoint":51},1222,"w4ec8yjkys2x8vb7t4zcote9","cover-lenivye-importy-v-python-3-15-kak-pep-810-uskoryaet-start-prilozhenij.webp",1672,941,{"thumbnail":67,"large":75,"medium":83,"small":91},{"name":68,"hash":69,"ext":54,"mime":55,"path":51,"width":70,"height":71,"size":72,"sizeInBytes":73,"url":74},"thumbnail_cover-lenivye-importy-v-python-3-15-kak-pep-810-uskoryaet-start-prilozhenij.webp","thumbnail_cover_lenivye_importy_v_python_3_15_kak_pep_810_uskoryaet_start_prilozhenij_2ead970066",245,138,3.36,3362,"\u002Fuploads\u002Fthumbnail_cover_lenivye_importy_v_python_3_15_kak_pep_810_uskoryaet_start_prilozhenij_2ead970066.webp",{"name":76,"hash":77,"ext":54,"mime":55,"path":51,"width":78,"height":79,"size":80,"sizeInBytes":81,"url":82},"large_cover-lenivye-importy-v-python-3-15-kak-pep-810-uskoryaet-start-prilozhenij.webp","large_cover_lenivye_importy_v_python_3_15_kak_pep_810_uskoryaet_start_prilozhenij_2ead970066",1000,563,13.32,13318,"\u002Fuploads\u002Flarge_cover_lenivye_importy_v_python_3_15_kak_pep_810_uskoryaet_start_prilozhenij_2ead970066.webp",{"name":84,"hash":85,"ext":54,"mime":55,"path":51,"width":86,"height":87,"size":88,"sizeInBytes":89,"url":90},"medium_cover-lenivye-importy-v-python-3-15-kak-pep-810-uskoryaet-start-prilozhenij.webp","medium_cover_lenivye_importy_v_python_3_15_kak_pep_810_uskoryaet_start_prilozhenij_2ead970066",750,422,9.92,9924,"\u002Fuploads\u002Fmedium_cover_lenivye_importy_v_python_3_15_kak_pep_810_uskoryaet_start_prilozhenij_2ead970066.webp",{"name":92,"hash":93,"ext":54,"mime":55,"path":51,"width":94,"height":95,"size":96,"sizeInBytes":97,"url":98},"small_cover-lenivye-importy-v-python-3-15-kak-pep-810-uskoryaet-start-prilozhenij.webp","small_cover_lenivye_importy_v_python_3_15_kak_pep_810_uskoryaet_start_prilozhenij_2ead970066",500,281,6.69,6686,"\u002Fuploads\u002Fsmall_cover_lenivye_importy_v_python_3_15_kak_pep_810_uskoryaet_start_prilozhenij_2ead970066.webp","cover_lenivye_importy_v_python_3_15_kak_pep_810_uskoryaet_start_prilozhenij_2ead970066",29.02,"\u002Fuploads\u002Fcover_lenivye_importy_v_python_3_15_kak_pep_810_uskoryaet_start_prilozhenij_2ead970066.webp","2026-11-13T11:44:04.223Z",[104],{"id":105,"documentId":106,"title":107,"published":108,"weight":109,"slug":110,"createdAt":111,"updatedAt":112,"publishedAt":113,"color":51},5,"j3ptvz8nc7ijk3w80s01koxc","Обзоры",true,4,"reviews","2026-11-12T11:20:31.440Z","2026-11-12T11:22:44.313Z","2026-11-12T11:22:44.297Z",{"pagination":115},{"page":116,"pageSize":117,"pageCount":116,"total":116},1,25,{"data":119,"meta":138},[120,126,132],{"published_date":121,"id":122,"documentId":123,"title":124,"slug":125},"2026-07-21",359,"hrh0asxfdodwjoioqkqwta73","Заглядывая в будущее: Postgres 19. REPACK, SQL\u002FPGQ и умный autovacuum","zaglyadyvaya-v-budushhee-postgres-19-repack-sql-pgq-i-umnyj-autovacuum",{"published_date":127,"id":128,"documentId":129,"title":130,"slug":131},"2026-07-10",348,"vtjvnrwjysp7pg2m5yplwrr5","TypeScript 7.0 — самое радикальное обновление за 10 лет","typescript-7-0-samoe-radikalnoe-obnovlenie-za-10-let",{"published_date":133,"id":134,"documentId":135,"title":136,"slug":137},"2026-06-30",346,"lhti4xw476nf25v1qburi3pg","PHP 8.6: дата релиза, предстоящие возможности и статус RFC","php-8-6-data-reliza-predstoyashhie-vozmozhnosti-i-status-rfc",{"pagination":139},{"page":116,"pageSize":140,"pageCount":140,"total":141},3,7,1794584601927]