
Относительно недавно приняли PEP-810 и началась ТОТАЛЬНАЯ ТРЯСКА, и я ее не понимаю.
PEP-810 - это нововведение, которое добавляет в Python поддержку явных ленивых импортов. Да-да, теперь можно писать:
lazy import jamlibи модуль jamlib не будет загружен до тех пор, пока ты реально не воспользуешься им в коде. Это может казаться мелочью, но на самом деле - большое изменение для всей экосистемы Python.
Зачем и кому это надо?
Почти все, что написано на python страдает проблемой долгого старта, особенно CLI инструменты. Даже если делаешь some-cli --help это может затянуться, т.к. питон начнет подгружать ВСЕ что объявлено в импортах, даже если --help никак их не трогает. Ленивые импорты решают эту проблему:
не обращаешься к
somelib- он не грузитсяне используешь какой-то модуль - он не грузится в
sys.modulesне используешь функцию - она не грузится в память
gcне тратит 100 лет на выгребание всего этого мусора после старта
Получаем:
быстрое время старта
меньше поедаем памяти
не исполняем код из импорта лишний раз
Как это работает?
В python введена новая синтаксическая конструкция lazy <import_action> <module>, например lazy import math или lazy from jamlib import Jam (Так же введен аргумент запуска python -X lazy_imports=all)
При этом:
Ленивые импорты работают только на глобальном уровне, в функции и классы их не прокинуть,
импортированный объект сначала - это прокси, который при первом обращении делает реальный импорт и заменяет себя настоящим объектом.
Пример:
lazy import jamlib
print("jamlib" in sys.modules) # False
print(jamlib.__version__) # Модуль явно вызывается
print("jamlib" in sys.modules) # TrueИ выглядит круто и на деле круто, но…
…в коммьюнити(особенно в русскоязычном) началась ТРЯСКА, я не буду тыкать пальцем в конкретных людей/каналы/посты, но я думаю вы видели этот поток возмущения, вот основные претензии:
Зачем нам ещё одно ключевое слово?!
Многие в сообществе возмутились, что lazy засоряет синтаксис. Мол, Python и так превращается в свалку ключевых слов ( async, match, теперь ещё lazy...). Было предложение использовать defer import, import(lazy), или вообще ничего не менять и продолжать писать import внутри функции.
Но это смешно, не нужно - не используй. Вот и все.
Ошибки теперь будут позже
Если без lazy ошибка импорта выскочит сразу, при запуске, то с lazy только когда модуль будет явно использован.
О ужас, это же реально все меняет (нет)! Для такого аргумента у меня один и тот же ответ: пиши тесты и код проверяй перед тем как лить куда-то.
Импорты имеют побочные эффекты
Да, импорты могут делать что-то важное при инициализации, но просто не засовывай их в lazy и не будет проблем.
Сложность растет
УУУУ СТАЛО СЛОЖНО, это же целое ключевое слово, лишняя магия. Давайте тогда вообще язык не развивать? Про типы вне typing тоже вой стоял, а сейчас хлебом не корми, дай тайпинга насыпать.
Я лично считаю, что PEP-810 - очень аккуратное и мощное улучшение. Оно не навязывается, оно даёт реальную пользу в больших проектах, и оно не ломает обратную совместимость. Да, баги могут стать чуть менее предсказуемыми. Но зато это шаг к более эффективному и современному Python. Главное - не злоупотреблять, а использовать, когда действительно есть польза.
А тряска - ну, Python-сообщество традиционно очень активно и страстно холиварит без повода. Но мне кажется, что PEP-810 останется, и через год все будут писать lazy import так же спокойно, как async def.