Опыт Python «Новые импортные крючки PEP-302» [закрыто]

41

Я один из разработчиков Ruby (CRuby). Мы работаем над выпуском Ruby 2.0 (запланировано на 2012 / февраль).

В Python есть «PEP302: новые импортные хуки» (2003):

Этот PEP предлагает добавить новый набор хуков импорта, которые предлагают лучшую настройку механизма импорта Python. В отличие от текущей ловушки импорта , в существующую схему можно внедрить ловушку нового стиля, позволяющую более точно контролировать, как находятся модули и как они загружаются.

Мы рассматриваем возможность добавления функции, подобной PEP302, в Ruby 2.0 (CRuby 2.0). Я хочу сделать предложение, которое может убедить Маца. В настоящее время CRuby может загружать сценарии только из файловых систем стандартным способом.

Если у вас есть опыт или соображения по поводу PEP 302, пожалуйста, поделитесь.

Пример:

  1. Это отличная спецификация. Нет необходимости менять это.
  2. Это почти хорошо, но есть проблема ...
  3. Если бы я мог вернуться к 2003 году, то я бы изменил спецификацию на ...
Коичи Сасада
источник
6
Вау, сам парень YARV, привет и добро пожаловать в Программисты! ;) На Stack Exchange нам действительно не нравятся открытые дискуссии, вместо этого мы любим решать конкретные проблемы (кратко прочитайте наш FAQ ) - я думаю, поэтому ваш вопрос закрыт по переполнению стека, и он уже имеет закрыть голосование здесь. Вы должны попытаться сделать это немного более конкретным - есть ли у вас особая озабоченность по поводу PEP 302, который мотивировал этот вопрос?
Яннис
4
Спасибо за ваш комментарий, Яннис. Я думаю, что я хочу обсудить «архитектуру программного обеспечения». PEP302 кажется мощной и общей структурой для расширения собственных загрузчиков на интерпретаторе Python. Тем не менее, мощная функция имеет такой риск, как чрезмерное использование (генерирует магические коды), препятствующее оптимизации интерпретатора. Поэтому я хочу знать, что этот фреймворк полезен для пользователей Python и разработчиков интерпретаторов. Я верю, что изучение истории поможет мне сделать хорошую спецификацию на Ruby 2.0.
Коичи Сасада
Спасибо, что изменили мой вопрос довольно. И мне жаль, если этот вопрос не является предпочтительным.
Коичи Сасада
Это фантастический пример того, как вопрос, который, на первый взгляд, не проходит наш тест «опрос общественного мнения», может, тем не менее, иметь удивительную ценность.
Росс Паттерсон

Ответы:

47

Я сопровождающий модуль runpy в Python и один из сопровождающих текущей системы импорта. Несмотря на то, что наша система импорта впечатляюще гибкая, я бы посоветовал не принимать ее оптом, не внося некоторых изменений - из-за проблем с обратной совместимостью, есть куча вещей, которые более неудобны, чем они могли бы быть в противном случае.

Одна вещь, которая мешает PEP 302 в Python, - это то, сколько времени нам понадобилось, чтобы перевести основную систему импорта на ее использование. На протяжении большей части десятилетия любой, кто делал что-то сложное с использованием ловушек импорта, застревал в реализации двух частей: одна обрабатывает загрузчики, совместимые с PEP 302 (например, импорт zip), а вторая - стандартный механизм импорта на основе файловой системы. Только в следующих версиях 3.3 обработка загрузчиков PEP 302 также позаботится об обработке модулей, импортированных с помощью стандартного механизма импорта файловой системы. Постарайтесь не повторять эту ошибку, если вы можете избежать ее.

PEP 420 (реализовано для Python 3.3) вносит некоторые дополнения в протокол, чтобы позволить импортерам добавлять части в пакеты пространства имен. Это также устраняет проблему именования в определении API Finder (фактически заменяя неправильно названный «find_module» более точным «find_loader»). Надеемся, что все это будет более четко задокументировано в спецификации языка к тому времени, когда 3.3rc1 появится через пару недель.

Другая заметная проблема заключается в том, что подход, документированный специально в PEP 302, имеет слишком большое глобальное состояние процесса. Не идите по этому пути - попробуйте инкапсулировать состояние в более согласованную объектную модель, чтобы немного легче выборочно импортировать другие модули (модули расширения C - основа для того, чтобы сделать любую такую ​​инкапсуляцию полностью эффективной, но даже некоторый уровень инкапсуляции может быть полезным)

В PEP 406 (http://www.python.org/dev/peps/pep-0406/) обсуждается возможная обратно совместимая эволюция подхода Python с улучшенной инкапсуляцией состояний. Если у вас есть модель инкапсулированного состояния с самого начала, тогда вы можете соответствующим образом определить свои API и избежать того, чтобы импортеры и загрузчики обращались к глобальному состоянию вообще (вместо того, чтобы передавать ссылку на активный механизм).

Еще одна недостающая часть в PEP 302 - это возможность запросить у импортера итератор для модулей, предоставляемых этим импортером (это необходимо для таких вещей, как утилиты замораживания и утилиты автоматической документации, которые извлекают строки документации). Так как это невероятно полезно, вам, вероятно, лучше было бы стандартизировать его с самого начала: http://docs.python.org/dev/library/pkgutil#pkgutil.iter_modules (мы, вероятно, в конце концов повысим это до формально определенного API в Python 3.4)

И мой последний комментарий заключается в том, что вы должны внимательно посмотреть на разделение ответственности между системой импорта и объектами загрузчика. В частности, рассмотрите возможность разделения API «load_module» на отдельные шаги «init_module» и «exec_module». Это должно позволить вам минимизировать степень, в которой загрузчики должны напрямую взаимодействовать с состоянием импорта.

PEP 302 и importlib являются отличной отправной точкой для более гибкой системы импорта, но мы определенно допустили ошибки, которых стоит избегать.

ncoghlan
источник
1
Они не совсем еще закончена, но первоначальный проект полной системы импорта документации можно найти на сайте docs.python.org/dev/reference/import
ncoghlan
1
python.org/dev/peps/pep-0451 - это обновление системы импорта Python для Python 3.4, в котором рассматриваются многие комментарии Бретта и меня.
ncoghlan
28

Рядом с ncoghlan я другой сопровождающий системы импорта Python и автор ее текущей реализации importlib (http://docs.python.org/dev/py3k/library/importlib.html). Со всем, что сказал Ник, я согласен, поэтому я просто хочу добавить дополнительную информацию.

Во-первых, не полагайтесь слишком сильно на PEP 302 напрямую, а вместо этого посмотрите на то, что importlib предоставляет в терминах абстрактных базовых классов и т. Д. Для обеспечения обратной совместимости все должно быть совместимо с PEP 302, но мне пришлось добавить некоторые из моих собственные API, чтобы закончить поддержку истинной гибкости.

Другим важным моментом является то, что вы даете разработчикам две части гибкости. Одним из них является возможность хранить код другим способом, а не просто напрямую в файловой системе (я называю это бэкэнд хранилища). для импорта), например, это позволяет коду жить в zip-файле, базе данных sqlite и т. Д. Другая поддержка заключается в том, что можно каким-то образом разрешить управление коду до или после обработки, например, Quixote (https://www.mems-exchange.org/software/quixote/) и альтернативное использование строковых литералов, не назначенных для переменную будет намного проще поддерживать.

В то время как последнее редко требуется, в первом случае вам нужно беспокоиться о поддержке. И в этом случае вы фактически переопределяете API взаимодействия с файловой системой. Поскольку некоторые люди нуждаются в ресурсах, хранящихся в виде файлов со своим кодом, вам необходимо обеспечить хороший способ чтения файлов, обнаружения файлов и т. Д. Нам все еще нужно реализовать часть API для обнаружения доступных файлов данных, их перечисления и т. Д. ,

Но тогда вам также понадобятся API-интерфейсы, специфичные для кода. Как упомянул Ник, вам в конечном итоге понадобятся API-интерфейсы для обнаружения модулей, содержащихся в пакете, и т. Д., Которые не относятся к конкретным файлам. Существует странная двойственность наличия API-интерфейсов для работы с модулями, в которых вы извлекли понятие файлов, но в конечном итоге вам необходимо предоставить API-интерфейсы для доступа к данным файловых активов. И как только вы пытаетесь реализовать одно в отношении другого, чтобы избежать дублирования, вода становится действительно мутной (то есть люди в конечном итоге полагаются на ожидаемое структурирование пути к файлу и т. Д., Не обращая внимания на тот факт, что путь может не быть истинным путем). потому что это для zip-файла, содержащего код, а не только файл). Итак, в конечном итоге вам придется реализовать два одинаковых API, но в конечном итоге вам будет лучше.

Как сказал Ник, наше решение является хорошей отправной точкой, но это не то, как я бы сделал это сегодня, если бы разрабатывал API с нуля.

Бретт Кэннон
источник
-1

PEP 302 позволяет вам подключиться к механизму импорта Python, то есть вы можете импортировать код из других источников, таких как базы данных, ZIP-файлы и так далее.

В импорте реализации Python существует длинная история сложности, которая только скоро будет упрощена введением реализации импорта в Python.

Я бы посоветовал долго и усердно думать о угловых делах. Тогда вы, вероятно, получите полезную реализацию.

holdenweb
источник