新聞中心
使用 importlib.metadata
3.8 新版功能.

在 3.10 版更改: importlib.metadata 不再是暫定的。
源代碼: Lib/importlib/metadata/__init__.py
importlib_metadata is a library that provides access to the metadata of an installed Distribution Package, such as its entry points or its top-level names (Import Packages, modules, if any). Built in part on python’s import system, this library intends to replace similar functionality in the entry point API and metadata API of pkg_resources. Along with importlib.resources, this package can eliminate the need to use the older and less efficient pkg_resources package.
importlib_metadata operates on third-party distribution packages installed into Python’s site-packages directory via tools such as pip. Specifically, it works with distributions with discoverable dist-info or egg-info directories, and metadata defined by the Core metadata specifications.
重要
These are not necessarily equivalent to or correspond 1:1 with the top-level import package names that can be imported inside Python code. One distribution package can contain multiple import packages (and single modules), and one top-level import package may map to multiple distribution packages if it is a namespace package. You can use package_distributions() to get a mapping between them.
By default, distribution metadata can live on the file system or in zip archives on sys.path. Through an extension mechanism, the metadata can live almost anywhere.
參見
https://importlib-metadata.readthedocs.io/
The documentation for importlib_metadata, which supplies a backport of importlib.metadata. This includes an API reference for this module’s classes and functions, as well as a migration guide for existing users of pkg_resources.
概述
Let’s say you wanted to get the version string for a Distribution Package you’ve installed using pip. We start by creating a virtual environment and installing something into it:
$ Python3 -m venv example$ source example/bin/activate(example) $ python -m pip install wheel
你可以通過運(yùn)行以下代碼得到``wheel``的版本字符串:
(example) $ python>>> from importlib.metadata import version>>> version('wheel')'0.32.3'
You can also get a collection of entry points selectable by properties of the EntryPoint (typically ‘group’ or ‘name’), such as console_scripts, distutils.commands and others. Each group contains a collection of EntryPoint objects.
你可以獲得 分發(fā)的元數(shù)據(jù):
>>> list(metadata('wheel'))['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']
你也可以獲得 分發(fā)的版本號(hào),列出它的 構(gòu)成文件,并且得到分發(fā)的 分發(fā)的依賴 列表。
功能性 API
這個(gè)包通過其公共 API 提供了以下功能。
入口點(diǎn)
entry_points() 函數(shù)返回入口點(diǎn)的字典。入口點(diǎn)表現(xiàn)為 EntryPoint 的實(shí)例;每個(gè) EntryPoint 對(duì)象都有 .name ,.group 與 .value 屬性,用于解析值的 .load() 方法, .module ,.attr 與 .extras 屬性是 .value 屬性的對(duì)應(yīng)部分。
查詢所有的入口點(diǎn):
>>> eps = entry_points()
The entry_points() function returns an EntryPoints object, a collection of all EntryPoint objects with names and groups attributes for convenience:
>>> sorted(eps.groups)['console_scripts', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools.installation']
EntryPoints 的 select 方法用于選擇匹配特性的入口點(diǎn)。要選擇 console_scripts 組中的入口點(diǎn):
>>> scripts = eps.select(group='console_scripts')
你也可以向 entry_points 傳遞關(guān)鍵字參數(shù) “group” 以實(shí)現(xiàn)相同的效果:
>>> scripts = entry_points(group='console_scripts')
選出命名為 “wheel” 的特定腳本(可以在 wheel 項(xiàng)目中找到):
>>> 'wheel' in scripts.namesTrue>>> wheel = scripts['wheel']
等價(jià)地,在選擇過程中查詢對(duì)應(yīng)的入口點(diǎn):
>>> (wheel,) = entry_points(group='console_scripts', name='wheel')>>> (wheel,) = entry_points().select(group='console_scripts', name='wheel')
檢查解析得到的入口點(diǎn):
>>> wheelEntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts')>>> wheel.module'wheel.cli'>>> wheel.attr'main'>>> wheel.extras[]>>> main = wheel.load()>>> main
The group and name are arbitrary values defined by the package author and usually a client will wish to resolve all entry points for a particular group. Read the setuptools docs for more information on entry points, their definition, and usage.
兼容性說明
“可選擇” 的入口點(diǎn)在 importlib_metadata 3.6,Python 3.10 中被引入。在此之前, entry_points 沒有形參且總是返回一個(gè)以分組為鍵,以入口點(diǎn)為值的字典。為了兼容性,如果不帶參數(shù)地調(diào)用 entry_points, 則會(huì)返回一個(gè)實(shí)現(xiàn)了字典接口的 SelectableGroups 對(duì)象。未來,不帶參數(shù)調(diào)用 entry_points 會(huì)返回 EntryPoints 對(duì)象。用戶只應(yīng)該依靠選擇接口來按組獲得入口點(diǎn)。
分發(fā)的元數(shù)據(jù)
Every Distribution Package includes some metadata, which you can extract using the metadata() function:
>>> wheel_metadata = metadata('wheel')
返回的數(shù)據(jù)架構(gòu) PackageMetadata 的鍵代表元數(shù)據(jù)的關(guān)鍵字,而值從分發(fā)的元數(shù)據(jù)中不被解析地返回:
>>> wheel_metadata['Requires-Python']'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
PackageMetadata 也提供了按照 PEP 566 將所有元數(shù)據(jù)以 JSON 兼容的方式返回的 json 屬性:
>>> wheel_metadata.json['requires_python']'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
備注
The actual type of the object returned by metadata() is an implementation detail and should be accessed only through the interface described by the PackageMetadata protocol.
在 3.10 版更改: 當(dāng)有效載荷中包含時(shí),Description 以去除續(xù)行符的形式被包含于元數(shù)據(jù)中。
3.10 新版功能: 添加了 json 屬性。
分發(fā)的版本
The version() function is the quickest way to get a Distribution Package‘s version number, as a string:
>>> version('wheel')'0.32.3'
分發(fā)的文件
You can also get the full set of files contained within a distribution. The files() function takes a Distribution Package name and returns all of the files installed by this distribution. Each file object returned is a PackagePath, a pathlib.PurePath derived object with additional dist, size, and hash properties as indicated by the metadata. For example:
>>> util = [p for p in files('wheel') if 'util.py' in str(p)][0]>>> utilPackagePath('wheel/util.py')>>> util.size859>>> util.dist>>> util.hash
當(dāng)你獲得了文件對(duì)象,你可以讀取其內(nèi)容:
>>> print(util.read_text())import base64import sys...def as_bytes(s):if isinstance(s, text_type):return s.encode('utf-8')return s
你也可以使用 locate 方法來獲得文件的絕對(duì)路徑:
>>> util.locate()PosixPath('/home/gustav/example/lib/site-packages/wheel/util.py')
當(dāng)列出包含文件的元數(shù)據(jù)文件(RECORD 或 SOURCES.txt)不存在時(shí), files() 函數(shù)將返回 None 。調(diào)用者可能會(huì)想要將對(duì) files() 的調(diào)用封裝在 always_iterable 中,或者用其他方法來應(yīng)對(duì)目標(biāo)分發(fā)元數(shù)據(jù)存在性未知的情況。
分發(fā)的依賴
To get the full set of requirements for a Distribution Package, use the requires() function:
>>> requires('wheel')["pytest (>=3.0.0) ; extra == 'test'", "pytest-cov ; extra == 'test'"]
Mapping import to distribution packages
A convenience method to resolve the Distribution Package name (or names, in the case of a namespace package) that provide each importable top-level Python module or Import Package:
>>> packages_distributions(){'importlib_metadata': ['importlib-metadata'], 'yaml': ['PyYAML'], 'jaraco': ['jaraco.classes', 'jaraco.functools'], ...}
3.10 新版功能.
分發(fā)
While the above API is the most common and convenient usage, you can get all of that information from the Distribution class. A Distribution is an abstract object that represents the metadata for a Python Distribution Package. You can get the Distribution instance:
>>> from importlib.metadata import distribution>>> dist = distribution('wheel')
因此,可以通過 Distribution 實(shí)例獲得版本號(hào):
>>> dist.version'0.32.3'
Distribution 實(shí)例具有所有可用的附加元數(shù)據(jù):
>>> dist.metadata['Requires-Python']'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'>>> dist.metadata['License']'MIT'
The full set of available metadata is not described here. See the Core metadata specifications for additional details.
Distribution Discovery
By default, this package provides built-in support for discovery of metadata for file system and zip file Distribution Packages. This metadata finder search defaults to sys.path, but varies slightly in how it interprets those values from how other import machinery does. In particular:
-
importlib.metadatadoes not honor bytes objects onsys.path. -
importlib.metadatawill incidentally honor pathlib.Path objects onsys.patheven though such values will be ignored for imports.
擴(kuò)展搜索算法
Because Distribution Package metadata is not available through sys.path searches, or package loaders directly, the metadata for a distribution is found through import system finders. To find a distribution package’s metadata, importlib.metadata queries the list of meta path finders on sys.meta_path.
By default importlib_metadata installs a finder for distribution packages found on the file system. This finder doesn’t actually find any distributions, but it can find their metadata.
抽象基類 importlib.abc.MetaPathFinder 定義了 Python 導(dǎo)入系統(tǒng)期望的查找器接口。 importlib.metadata 通過尋找 sys.meta_path 上查找器可選的 find_distributions 可調(diào)用的屬性擴(kuò)展這個(gè)協(xié)議,并將這個(gè)擴(kuò)展接口作為 DistributionFinder 抽象基類提供,它定義了這個(gè)抽象方法:
@abc.abstractmethoddef find_distributions(context=DistributionFinder.Context()):"""Return an iterable of all Distribution instances capable ofloading the metadata for packages for the indicated ``context``."""
DistributionFinder.Context 對(duì)象提供了指示搜索路徑和匹配名稱的屬性 .path 和 .name ,也可能提供其他相關(guān)的上下文。
這在實(shí)踐中意味著要支持在文件系統(tǒng)外的其他位置查找分發(fā)包的元數(shù)據(jù),你需要子類化 Distribution 并實(shí)現(xiàn)抽象方法,之后從一個(gè)自定義查找器的 find_distributions() 方法返回這個(gè)派生的 Distribution 實(shí)例。
本文標(biāo)題:創(chuàng)新互聯(lián)Python教程:使用importlib.metadata
本文URL:http://fisionsoft.com.cn/article/cddpdds.html


咨詢
建站咨詢
