Доступ к файлам в яйце питона из яйца

Вопрос заключается в попытке получить точную инструкцию о том, как это сделать. Ранее было несколько попыток, которые, похоже, не являются полными решениями:

решение для перемещения файла внутри пакета

решение читать как zip

доступ к метаинформации через get_distribution

Задача состоит в том, чтобы прочитать информацию о яйце, из которого запущена программа. Есть несколько способов, как я понимаю:

  • жесткий код местоположения яйца и рассматривать его как zip-архив - будет работать, но не достаточно гибко, потому что его нужно будет отредактировать и перекомпилировать, если файл перенесен в другое место

  • use ResourceManager().resource_filename(__name__, filename) - это, по-видимому, ограничено тем фактом, что я не могу получить доступ к файлу, который находится внутри яйца, но не внутри пакета. Такие обозначения, как "../../EGG-INFO/PKG-INFO" в имени файла, не работают с KeyError. Так что ничего хорошего.

  • используйте dist = pkg_resources.get_distribution("dist_name"), а затем используйте объект dist для получения информации, но я не могу понять из документов, как мне указать имя моего дистрибутива? Он не может его найти.

Итак, я ищу правильное решение об использовании pkg_resources.get_distribution плюс, было бы неплохо наконец иметь полное решение для чтения любого файла изнутри яйца.

Спасибо!

Ответ 1

Setuptools/distribute/pkg_resources предназначен для своего рода прозрачного наложения на стандартные дистрибутивы Python, которые довольно ограничены и не позволяют использовать хороший способ распространения кода.

яйца - это всего лишь способ собрать кучу файлов python, файлов данных и метаданных, несколько похожих на Java JAR, но пакеты python могут быть установлены из источника даже без en egg (что является концепцией, которая не существует в стандартном распределении).

Итак, есть два сценария: либо вы программист, который пытается использовать какой-либо файл внутри библиотеки, и в этом случае, чтобы читать любой файл из вашего дистрибутива, вам не нужен его полный путь - вам просто нужен открытый файл с его содержимым, верно? Поэтому вы должны сделать что-то вроде этого:

from pkg_resources import resource_stream, Requirement
resource_stream(Requirement.parse("restez==0.3.2"), "restez/httpconn.py")

Это вернет открытый, читаемый файл файла, который вы запросили, из вашего дистрибутива пакета. Если это застегнутое яйцо, оно будет автоматически извлечено.

Обратите внимание, что вы должны указать имя пакета внутри (restez), потому что имя дистрибутива может отличаться от пакета (например, дистрибутив Twisted затем использует имя скрученного пакета). Анализ синтаксиса синтаксиса: http://setuptools.readthedocs.io/en/latest/pkg_resources.html#requirements-parsing

Этого должно быть достаточно - вам не нужно знать путь яйца, как только вы узнаете, как извлекать файлы из яйца.

Если вам действительно нужен полный путь, и вы уверены, что ваше яйцо несжато, используйте resource_filename вместо resource_stream.

В противном случае, если вы создаете "инструмент для упаковки" и вам нужно получить доступ к содержимому вашего пакета, будь то яйцо или что-нибудь еще, вам придется делать это вручную, так же как pkg_resources делает (источник pkg_resources). Там нет точного API для "запроса содержимого яйца", потому что для этого нет смысла. Если вы программист, просто используя библиотеку, используйте pkg_resources, как я и предложил. Если вы строите инструмент для упаковки, вы должны знать, где положить руки и что это.

Ответ 2

zipimporter, который используется для загрузки модуля, можно получить с помощью __loader__ в модуле, поэтому доступ к файлу внутри яйца должен быть таким же простым, как:

__loader__.get_data('path/within/the/egg')