Документация Python неофициальный перевод

importlib.metadata.md

190 строк · 14.6 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.8/library/importlib.metadata.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Использование `importlib.metadata`89Новое в версии 3.8.1011**Исходный код:** [Lib/importlib/metadata.py](https://python-all.ru/src/3.8/Lib/importlib/metadata.py)1213> **Примечание**14>15> Эта функциональность является предварительной и может отклоняться от обычной семантики версий стандартной библиотеки.1617`importlib.metadata` – это библиотека, обеспечивающая доступ к метаданным установленных пакетов. Частично основанная на системе импорта Python, эта библиотека призвана заменить аналогичную функциональность в [точки входа API](https://python-all.ru/3.8/library/importlib.metadata.html) и [API метаданных](https://python-all.ru/3.8/library/importlib.metadata.html) из `pkg_resources`. Вместе с [`importlib.resources`](https://python-all.ru/3.8/library/importlib.html#module-importlib.resources) (начиная с Python 3.7 и новее, с обратным портированием как [importlib\_resources](https://python-all.ru/3.8/library/importlib.metadata.html) для более старых версий Python), это позволяет отказаться от использования устаревшего и менее эффективного пакета `pkg_resources`.1819Под «установленным пакетом» обычно понимается сторонний пакет, установленный в каталог `site-packages` Python с помощью таких инструментов, как [pip](https://python-all.ru/3.8/library/importlib.metadata.html). В частности, это пакет, имеющий либо обнаруживаемый каталог `dist-info` или `egg-info` и метаданные, определённые [**PEP 566**](https://python-all.ru/3.8/library/importlib.metadata.html) или более старыми спецификациями. По умолчанию метаданные пакета могут находиться в файловой системе или в zip-архивах на [`sys.path`](https://python-all.ru/3.8/library/sys.html#sys.path). Благодаря механизму расширения метаданные могут находиться практически где угодно.2021## Обзор2223Предположим, вы хотите получить строку версии для пакета, установленного с помощью `pip`. Начнём с создания виртуального окружения и установки чего-нибудь в него:2425```console26$ python3 -m venv example27$ source example/bin/activate28(example) $ pip install wheel29```3031Вы можете получить строку версии для `wheel`, выполнив следующее:3233```pycon34(example) $ python35>>> from importlib.metadata import version  36>>> version('wheel')  37'0.32.3'38```3940Также можно получить набор точек входа, разбитых по группам, таких как `console_scripts`, `distutils.commands` и другие. Каждая группа содержит последовательность объектов [EntryPoint](https://python-all.ru/3.8/library/importlib.metadata.html#entry-points).4142Вы можете получить [метаданные для дистрибутива](https://python-all.ru/3.8/library/importlib.metadata.html#metadata):4344```python45>>> list(metadata('wheel'))  46['Metadata-Version', 'Name', 'Version', 'Summary', 'Home-page', 'Author', 'Author-email', 'Maintainer', 'Maintainer-email', 'License', 'Project-URL', 'Project-URL', 'Project-URL', 'Keywords', 'Platform', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Requires-Python', 'Provides-Extra', 'Requires-Dist', 'Requires-Dist']47```4849Вы также можете получить [номер версии дистрибутива](https://python-all.ru/3.8/library/importlib.metadata.html#version), перечислить его [составные файлы](https://python-all.ru/3.8/library/importlib.metadata.html#files) и получить список [зависимостей дистрибутива](https://python-all.ru/3.8/library/importlib.metadata.html#requirements).5051## Функциональное API5253Этот пакет предоставляет следующие функции через свой публичный API.5455### Точки входа5657Функция `entry_points()` возвращает словарь всех точек входа, сгруппированных по группам. Точки входа представлены экземплярами `EntryPoint`; каждый `EntryPoint` имеет атрибуты `.name`, `.group` и `.value`, а также метод `.load()` для определения значения.5859```python60>>> eps = entry_points()  61>>> list(eps)  62['console_scripts', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools.installation']63>>> scripts = eps['console_scripts']  64>>> wheel = [ep for ep in scripts if ep.name == 'wheel'][0]  65>>> wheel  66EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts')67>>> main = wheel.load()  68>>> main  69<function main at 0x103528488>70```7172`group` и `name` – произвольные значения, определяемые автором пакета. Обычно клиент хочет получить все точки входа для определённой группы. Прочтите [документацию setuptools](https://python-all.ru/3.8/library/importlib.metadata.html), чтобы узнать больше о точках входа, их определении и использовании.7374### Метаданные дистрибутива7576Каждый дистрибутив содержит некоторые метаданные, которые можно извлечь с помощью функции `metadata()`:7778```python79>>> wheel_metadata = metadata('wheel')  80```8182Ключи возвращаемой структуры данных [1](https://python-all.ru/3.8/library/importlib.metadata.html#f1) именуют ключевые слова метаданных, а их значения возвращаются без разбора из метаданных дистрибутива:8384```python85>>> wheel_metadata['Requires-Python']  86'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'87```8889### Версии дистрибутивов9091Функция `version()` – это самый быстрый способ получить номер версии дистрибутива в виде строки:9293```python94>>> version('wheel')  95'0.32.3'96```9798### Файлы дистрибутива99100Также можно получить полный набор файлов, содержащихся в дистрибутиве. Функция `files()` принимает имя пакета дистрибутива и возвращает все файлы, установленные этим дистрибутивом. Каждый возвращаемый файловый объект – это `PackagePath`, производный объект [`pathlib.Path`](https://python-all.ru/3.8/library/pathlib.html#pathlib.Path) с дополнительными свойствами `dist`, `size` и `hash`, как указано в метаданных. Например:101102```python103>>> util = [p for p in files('wheel') if 'util.py' in str(p)][0]  104>>> util  105PackagePath('wheel/util.py')106>>> util.size  107859108>>> util.dist  109<importlib.metadata._hooks.PathDistribution object at 0x101e0cef0>110>>> util.hash  111<FileHash mode: sha256 value: bYkw5oMccfazVCoYQwKkkemoVyMAFoR34mmKBx8R1NI>112```113114Получив файл, можно также прочитать его содержимое:115116```python117>>> print(util.read_text())  118import base64119import sys120...121def as_bytes(s):122    if isinstance(s, text_type):123        return s.encode('utf-8')124    return s125```126127В случае, если файл метаданных со списком файлов (RECORD или SOURCES.txt) отсутствует, `files()` вернёт `None`. Вызывающий код может обернуть вызовы `files()` в [always\_iterable](https://python-all.ru/3.8/library/importlib.metadata.html) или иным образом защититься от этой ситуации, если неизвестно, что целевой дистрибутив содержит метаданные.128129### Зависимости дистрибутивов130131Чтобы получить полный набор зависимостей для дистрибутива, используйте функцию `requires()`:132133```python134>>> requires('wheel')  135["pytest (>=3.0.0) ; extra == 'test'", "pytest-cov ; extra == 'test'"]136```137138## Дистрибутивы139140Хотя приведённый выше API является наиболее распространённым и удобным способом использования, всю эту информацию можно получить из класса `Distribution`. `Distribution` – это абстрактный объект, представляющий метаданные для пакета Python. Можно получить экземпляр `Distribution`:141142```python143>>> from importlib.metadata import distribution  144>>> dist = distribution('wheel')  145```146147Таким образом, альтернативный способ получить номер версии – через экземпляр `Distribution`:148149```python150>>> dist.version  151'0.32.3'152```153154На экземпляре `Distribution` доступны всевозможные дополнительные метаданные:155156```python157>>> dist.metadata['Requires-Python']  158'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'159>>> dist.metadata['License']  160'MIT'161```162163Полный набор доступных метаданных здесь не описан. Подробнее см. [**PEP 566**](https://python-all.ru/3.8/library/importlib.metadata.html) .164165## Расширение алгоритма поиска166167Поскольку метаданные пакета недоступны через поиск [`sys.path`](https://python-all.ru/3.8/library/sys.html#sys.path) или напрямую через загрузчики пакетов, метаданные пакета находятся через систему импорта [искатели](https://python-all.ru/3.8/reference/import.html#finders-and-loaders). Чтобы найти метаданные пакета дистрибутива, `importlib.metadata` запрашивает список [искателей метапути](https://python-all.ru/3.8/glossary.html#term-meta-path-finder) в [`sys.meta_path`](https://python-all.ru/3.8/library/sys.html#sys.meta_path).168169Стандартный `PathFinder` для Python включает хук, который вызывает `importlib.metadata.MetadataPathFinder` для поиска дистрибутивов, загруженных из типичных путей файловой системы.170171Абстрактный класс [`importlib.abc.MetaPathFinder`](https://python-all.ru/3.8/library/importlib.html#importlib.abc.MetaPathFinder) определяет интерфейс, ожидаемый от искателей системой импорта Python. `importlib.metadata` расширяет этот протокол, проверяя наличие опционального вызываемого объекта `find_distributions` у искателей из [`sys.meta_path`](https://python-all.ru/3.8/library/sys.html#sys.meta_path), и предоставляет этот расширенный интерфейс как абстрактный базовый класс `DistributionFinder`, который определяет следующий абстрактный метод:172173```python174@abc.abstractmethod175def find_distributions(context=DistributionFinder.Context()):176    """Возвращает итерируемый объект со всеми экземплярами Distribution, способными177    загружать метаданные для пакетов для указанного ``context``.178    """179```180181Объект `DistributionFinder.Context` предоставляет свойства `.path` и `.name`, указывающие путь для поиска и имена для сопоставления, и может предоставлять другой соответствующий контекст.182183На практике это означает, что для поддержки поиска метаданных дистрибутивного пакета в местах, отличных от файловой системы, нужно создать подкласс `Distribution` и реализовать абстрактные методы. Затем из пользовательского находильщика возвращать экземпляры этого производного `Distribution` в методе `find_distributions()`.184185Сноски186187**[1](https://python-all.ru/3.8/library/importlib.metadata.html#id2)**188189Технически, возвращаемый объект метаданных дистрибутива является [`email.message.EmailMessage`](https://python-all.ru/3.8/library/email.message.html#email.message.EmailMessage) экземпляром, но это деталь реализации и не является частью стабильного API. Следует использовать только методы и синтаксис, подобные словарю, для доступа к содержимому метаданных.190