首页
/ CPython 中 importlib.metadata 完全指南:读取已安装发行包元数据、入口点与依赖信息

CPython 中 importlib.metadata 完全指南:读取已安装发行包元数据、入口点与依赖信息

2026-09-07 15:12:18作者:苗圣禹Peter

importlib.metadata 是 CPython 标准库中用于读取已安装第三方「发行包」(Distribution Package)元数据的模块,它提供获取版本号、入口点(entry points)、构成文件、依赖声明等功能,并在 Python 3.8 起随标准库发布、3.10 起不再标记为 provisional。本文以 CPython 仓库中的官方文档 Doc/library/importlib.metadata.rst 为主线,结合其实现源码 Lib/importlib/metadata/init.py 与单元测试,系统地讲解它的函数式 API、面向对象的 Distribution 接口、发行包发现机制,以及如何为自定义元数据源实现 Provider。读完本文,你将能准确区分「发行包」与「导入包」、熟练查询任意已安装包的信息,并掌握扩展该模块到文件系统与 zip 之外的元数据源的完整方法。

概览:发行包元数据与 importlib.metadata 的定位

importlib.metadata 是一个专门读取已安装发行包元数据的库,操作对象是通过 pip 等工具安装到 Python 的 site-packages 目录下的第三方发行包。它能够读取其中带有可发现的 dist-infoegg-info 目录的发行包,并按 Packaging 领域的 Core metadata 规范解析 METADATA 等元数据文件。

该模块建立在 Python 导入系统之上(MetaPathFinder / sys.meta_path),提供了一套曾由现已移除的 pkg_resources 暴露的入口点与元数据 API;与 importlib.resources 一起,它取代了 pkg_resources 的职责。从源码看,整个功能由 Lib/importlib/metadata/init.py 一个约 1200 行的文件承载,并按职责拆分到 _adapters.pyemail.message 元数据适配)、_meta.pyPackageMetadata 协议与 SimplePath 协议)、_collections.py_context.py_functools.py_itertools.py_text.py_typing.py 等辅助模块,另有 diagnose.py 提供诊断工具。该代码库与 PyPI 上的 importlib_metadata(即本模块的 backport)共享同一份实现。

关键概念:发行包 ≠ 导入包

文档特别强调:发行包与可被 import 的顶层导入包名并不一一对应

  • 一个发行包可能包含多个导入包或独立模块;
  • 一个顶层导入包(如 namespace package)可能由多个发行包共同提供。

因此,如果你需要反向查询「某个可导入的顶层模块由哪个发行包提供」,应使用下文的 packages_distributions() 函数。默认情况下,元数据可以存放在文件系统中,也可以存放在位于 sys.path 上的 zip 归档内;通过扩展机制(自定义 Provider),元数据几乎可以存放在任意位置。

快速上手:虚拟环境与第一个查询

文档给出了一条完整的实操路径。首先创建虚拟环境并安装一个示例包(以 wheel 为例):

$ python -m venv example
$ source example/bin/activate
(example) $ python -m pip install wheel

随后在 Python 交互环境中即可用 version() 取到版本号:

(example) $ python
>>> from importlib.metadata import version
>>> version('wheel')
'0.32.3'

这就是最典型的使用场景:工具链(构建工具、包管理器、CLI 框架)在运行时反查某个依赖的版本,无需 import 该包本身。与之配合的还有三组常用能力:按属性筛选入口点、查看 METADATA 全文,以及列出构成文件与依赖,下文逐一展开。

函数式 API 全解

模块级函数是最常用的便捷入口,均接收一个发行包名字符串并返回相应信息;若环境中不存在该发行包,则抛出 PackageNotFoundError

两个内置异常

在函数式 API 中会首先遇到两个异常,其定义见源码 Lib/importlib/metadata/init.py 第 59–72 行:

  • PackageNotFoundError:class:ModuleNotFoundError 的子类。当所查询的发行包未安装在当前 Python 环境中时,由本模块多个函数抛出。源码中 Distribution.from_name()discover(name=name) 找不到任何结果时 raise PackageNotFoundError(name)
  • MetadataNotFound:class:FileNotFoundError 的子类。当尝试从一个空的或不含元数据文件的发行目录加载元数据时抛出。源码中的 Distribution._ensure_metadata_present() 在读取不到 METADATA(及旧式 PKG-INFO)文本时直接 raise MetadataNotFound('No package metadata was found.')

入口点(Entry Points):entry_points()EntryPointsEntryPoint

入口点是在包的元数据中声明的、可被外部按「组」发现的具名对象引用,常见的组包括 console_scripts(命令行脚本)、distutils.commands 等。entry_points(**select_params) 返回描述当前环境所有入口点的 EntryPoints 实例;传入的关键字参数会被透传给 EntryPoints.select(),与各入口点定义的属性逐一比较。

从源码实现看,模块级 entry_points() 是先遍历全部发行包、收集各自 entry_points 后构造 EntryPoints(eps).select(**params)Lib/importlib/metadata/init.py 第 1113–1125 行)。查询所有入口点、并按组筛选的典型用法如下:

>>> eps = entry_points()

返回的 EntryPoints 是一个不可变、可选代的集合对象(内部是 tuple 的子类),并提供两个便捷属性:

  • .groups:全部已识别入口点「组」名的集合;
  • .names:全部已识别入口点「名称」的集合。
>>> sorted(eps.groups)
['console_scripts', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools.installation']

EntryPoints 还提供 select() 方法,按指定属性筛选入口点。筛选 console_scripts 组中的入口点,以下两种写法等价(因为 entry_points() 会把关键字参数透传给 select):

>>> scripts = eps.select(group='console_scripts')
>>> scripts = entry_points(group='console_scripts')

进一步挑出名为 "wheel" 的脚本(该入口点由 wheel 项目提供),可用 names 判断存在性、用下标直接取:

>>> 'wheel' in scripts.names
True
>>> wheel = scripts['wheel']

也可以在调用 entry_points / select 时同时给出 groupname

>>> (wheel,) = entry_points(group='console_scripts', name='wheel')
>>> (wheel,) = entry_points().select(group='console_scripts', name='wheel')

得到单个 EntryPoint 后即可检视并解析它:

>>> wheel
EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts')
>>> wheel.module
'wheel.cli'
>>> wheel.attr
'main'
>>> wheel.extras
[]
>>> main = wheel.load()
>>> main
<function main at 0x103528488>

EntryPoint 对象的关键属性与方法如下:

  • .name.group.value:入口点定义的三个原始字段;
  • .module.attr.extrasvalue 的解析结果,分别对应模块名、属性路径与(方括号声明的)可选依赖 extra 列表;
  • .dist:提供该入口点的发行包对应的 Distribution 对象(注意:源码中通过 EntryPoints._from_text_for(text, dist) 在解析时把 dist 绑定到每个 EntryPoint 上,见第 361–370 行);
  • .load():解析 value 指向的实际对象。其实现是先 import_module(self.module),再用 functools.reduce(getattr, attrs, module) 沿点号路径逐级取属性(见第 218–225 行)。

从源码可见 value 字段由正则 (?P<module>[\w.]+)\s*(:\s*(?P<attr>[\w.]+)\s*)?((?P<extras>\[.*\])\s*)?$ 校验(第 187–191 行),支持 modulepackage.module:attributepackage.module:object.attribute 以及带 extras 的多种形态。若对象引用非法,会在构造或访问属性时抛出 ValueErrorgroupname 由包作者自定义,通常客户端会解析某个特定组内的全部入口点。

兼容性说明entry_points() 在 Python 3.10 前不接受参数并总是返回按组键控的字典;自 3.12 起它总是返回 EntryPoints 对象(importlib_metadata 对应在 5.0 版对齐该行为)。另外自 3.13 起 EntryPoint 不再提供类元组的下标接口(不再支持 ep[0] 式访问)。

发行包元数据:metadata()PackageMetadata

每个发行包都包含元数据,用 metadata(distribution_name) 可将其作为 PackageMetadata 实例取出:

>>> wheel_metadata = metadata('wheel')

PackageMetadataPackageMetadata 协议的具体实现,其键为元数据关键字,值原样来自发行包元数据(不做解析),例如:

>>> wheel_metadata['Requires-Python']
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'

需要注意两个约定:

  • 对实例做下标访问等价于调用其 get() 方法;
  • PackageMetadata 还提供一个 .json 属性,按 PEP 566 以 JSON 兼容形态返回全部元数据:
>>> wheel_metadata.json['requires_python']
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'

metadata('wheel') 直接取键,可以看到一条 METADATA 中常见的完整字段清单(这里演示的是 wheel 包发行时生成的元数据,实际字段由打包工具决定):

>>> 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']

源码层面,metadata() 简化为 Distribution.from_name(...).metadata(第 1084–1091 行)。metadata 属性的实现会依次尝试读取 METADATA、旧式 PKG-INFO 乃至空文件名(兼容老 egg-info 目录),再经 email.message_from_string_adapters.Message 包装成 PackageMetadata(第 535–550 行)。

行为变更(面向 Python 3.15,见仓库文档):早期若发行包缺失 METADATA 文件,会返回一个空的 PackageMetadata,与「空 METADATA 文件」无法区分;现在缺失 METADATA 会触发 MetadataNotFound 异常。此外自 3.10 起,Description 已包含在元数据 payload 中,且行续接符被移除;.json 属性也是 3.10 加入的。完整可用元数据字段集不在此赘述,详见 Packaging 社区的 Core metadata 规范。

发行包版本号:version()

version(distribution_name) 是最快捷地取得发行包版本号(字符串)的函数,等价于 distribution(distribution_name).version(源码第 1094–1101 行),实现上直接读取元数据中的 Version 键:

>>> version('wheel')
'0.32.3'

发行包文件清单:files()PackagePathSimplePath

files(distribution_name) 返回该发行包所含全部文件的 PackagePath 实例集合。PackagePathpathlib.PurePosixPath 的派生对象(源码第 373–388 行),并附带了来自安装记录(RECORD)的元信息属性:

  • .dist:该文件所属的 Distribution 实例;
  • .size:文件字节数;
  • .hashFileHash 对象,携带模式(如 sha256)与摘要值。

例如从 wheel 包中定位 util.py

>>> util = [p for p in files('wheel') if 'util.py' in str(p)][0]
>>> util
PackagePath('wheel/util.py')
>>> util.size
859
>>> util.dist
<importlib.metadata._hooks.PathDistribution object at 0x101e0cef0>
>>> util.hash
<FileHash mode: sha256 value: bYkw5oMccfazVCoYQwKkkemoVyMAFoR34mmKBx8R1NI>

拿到文件后可以直接读取内容或定位绝对路径:

>>> print(util.read_text())
import base64
import sys
...
def as_bytes(s):
    if isinstance(s, text_type):
        return s.encode('utf-8')
    return s
>>> util.locate()
PosixPath('/home/gustav/example/lib/site-packages/wheel/util.py')

locate() 若能实现则返回可访问数据的具体 SimplePathlocate() 的内部实现是 self.dist.locate_file(self),见第 386–388 行),否则抛出 NotImplementedErrorSimplePath 是一个协议(定义于 Lib/importlib/metadata/_meta.py),表示 pathlib.Path 的最小化子集:支持 exists()joinpath()parent 遍历,以及 read_text()read_bytes() 取数。

容错要点:如果列举文件的元数据(RECORD 或旧式 SOURCES.txt)缺失,files() 会返回 None 而非抛出异常(返回 None 的判定逻辑见源码第 606–624 行)。当不确定目标发行包是否携带该记录时,建议调用方用 always_iterable 之类的工具包装返回值,或自行判空。另外若文件已不在磁盘上,files() 会通过 skip_missing_files 将其过滤掉。

发行包依赖:requires()

requires(distribution_name) 返回该发行包声明的依赖说明符列表,返回项可直接交给 packaging.requirement.Requirement 之类的解析器处理:

>>> requires('wheel')
["pytest (>=3.0.0) ; extra == 'test'", "pytest-cov ; extra == 'test'"]

从源码可见,requires 属性对 dist-info 形态直接取 METADATA 中所有 Requires-Dist 字段;对旧式 egg-info 则读取 requires.txt,并将其按小节组织的 extras/环境标记转换为每行独立的、带 ; extra == "..." 条件的 PEP 508 说明符(见第 676–726 行的 _convert_egg_info_reqs_to_simple_reqs)。

导入包 → 发行包反向映射:packages_distributions()

packages_distributions() 返回从顶层模块/导入包名提供它的发行包名列表的映射。之所以值是列表而非单个名字,是为了容纳 namespace package——其成员可能由多个发行包分别提供:

>>> packages_distributions()
{'importlib_metadata': ['importlib-metadata'], 'yaml': ['PyYAML'], 'jaraco': ['jaraco.classes', 'jaraco.functools'], ...}

从实现看(第 1147–1161 行),该函数优先读取发行包显式声明的 top_level.txt_top_level_declared),缺失时再从文件清单推断(_top_level_inferred,例如把 foo/__init__.py 归为顶层名 foo)。需要说明:部分可编辑安装(editable install)不提供顶层名字信息,因此该函数对这类安装并不完全可靠。该函数自 Python 3.10 起可用。

面向对象 API:Distribution

模块级函数虽然最常用,但全部信息都能从 Distribution 类获得。Distribution 是一个抽象对象,代表某个发行包的元数据,其抽象基类定义见源码第 399 行起。取到某发行包对应实例的方法是 distribution()

>>> from importlib.metadata import distribution
>>> dist = distribution('wheel')
>>> type(dist)
<class 'importlib.metadata.PathDistribution'>

默认情况下,文件系统上发现的发行包对应的是 PathDistribution 这一具体子类(见下文「发现机制」)。于是版本号等信息也可用面向对象方式获得:

>>> dist.version
'0.32.3'

entry_points()files() 也有同样的 dist.entry_pointsdist.files 属性对应物。

构造与发现入口

Distribution 提供以下类方法(实现见第 452–519 行):

  • Distribution.at(path)(静态方法):在给定路径上构造发行包实例,实际返回 PathDistribution(pathlib.Path(path))
  • Distribution.from_name(name)(类方法):按名字返回发行包,找不到时抛 PackageNotFoundError
  • Distribution.discover(*, context=None, **kwargs)(类方法):返回所有发行包的 Distribution 迭代器;可选参数 contextDistributionFinder.Context 实例,也可直接用关键字参数构造新的 Context。实现会遍历 sys.meta_path 上所有实现了 find_distributions 的 finder(_discover_resolvers),并链式拼接其结果。

属性速查

文档罗列了 Distribution 上的常用属性:

  • metadataPackageMetadata):完整元数据;METADATA 缺失时抛 MetadataNotFound。可像字典一样取键:
>>> dist.metadata['Requires-Python']
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
>>> dist.metadata['License']
'MIT'
  • namestr):读取 Name 字段的快捷属性(3.10 加入);
  • requireslist[str]):依赖说明符;
  • versionstr):版本号;
  • origin:对可编辑(editable)安装,呈现 PEP 610 的 direct_url.json 直链元数据;对普通安装为 None(3.13 加入):
>>> dist.origin.url
'file:///path/to/wheel-0.32.3.editable-py3-none-any.whl'

origin 对象遵循 Packaging 的 Direct URL 数据结构(源码通过 _load_json('direct_url.json') 并以 SimpleNamespace 形式返回,见第 728–739 行)。

  • entry_pointsEntryPoints):本发行包提供的入口点;
  • fileslist[PackagePath] | None):本发行包的全部文件,与 files() 一致——无记录时返回 None

两个抽象方法(供自定义 Provider 实现)

自定义 Provider 必须实现以下两个抽象方法(第 410–448 行):

  • locate_file(path):类似 PackagePath.locate,为给定路径(os.PathLikestr)返回 SimplePath
  • read_text(filename):等价于 distribution.locate_file(filename).read_text() 的便捷方法。

注意两个说明:不同的 Distribution 实例目前比较相等,即使它们指向同一安装且属性相同——这正是不推荐用 entry_points().select(dist=...)dist 过滤的原因,官方建议改用 Distribution.entry_points。此外,由于 dist 不可比较,EntryPoint.matches() 会对按 dist 查询直接抛出 ValueError

发行包发现机制(Distribution Discovery)

默认情况下,内置支持发现位于文件系统与 zip 归档中的发行包元数据。发现器默认沿 sys.path 搜索,但 importlib.metadatasys.path 上取值类型的解释与常规导入机制略有差异,文档明确列出两点:

  • importlib.metadata 理会 sys.path 上的 bytes 对象;
  • importlib.metadata 会顺带理会 sys.path 上的 pathlib.Path 对象——尽管这类值在常规导入时会被忽略。

DistributionFinderimportlib.abc.MetaPathFinder 的子类,具备发现已安装发行包的能力;自定义 Provider 应实现该接口以提供元数据。它内嵌一个 Context 类,给自定义 Provider 提供一条「从调用方获取搜索条件以外的额外上下文」的通道:除了规范化的 namepath,调用方可自由传入任意关键字参数。例如某 Provider 把包按 realm 划分为 public/private 两套,调用方就可执行 distributions(realm="private"),由该 Provider 决定如何解读。

Context 的两个规范化属性为(实现见第 750–791 行):

  • name:finder 应匹配的具体名字;值为 None 时匹配所有发行包;
  • path:finder 应搜索的目录序列(属性),通常指 site-packages 等 Python 包安装路径,默认回退到 sys.path

distributions(**kwargs) 返回环境中全部发行包的 Distribution 迭代器;kwargs 可传入关键字 context(一个 DistributionFinder.Context 实例),或直接给出用于构造新 Context 的关键字参数。模块级 entry_points() 正是基于 distributions() 收集全部入口点后再做筛选(源码第 1122–1125 行),并用按规范化名字去重的包装器 _unique 避免同一发行包因 sys.path 上多路径命中而被重复计入。

内置文件系统实现与性能细节

仓库提供了文件系统侧的默认实现,理解它有助于排查行为差异:

  • MetadataPathFinder(第 983–1009 行)是内置 DistributionFinder,其 find_distributionscontext.path 中每个目录执行 FastPath.search(prepared)
  • Prepared(第 927–980 行)预计算名字规范化:normalize 按 PEP 503 规则(小写、-_._、合并连续下划线)用于 dist-infolegacy_normalize 用于旧式 egg-info
  • Lookup(第 876–924 行)扫描目录,凡以 .dist-info / .egg-info 结尾的子目录都会在首次构建索引时被登记;
  • FastPath(第 818–873 行)做缓存与微优化:其 __new__functools.lru_cache 缓存(同一 root 复用同一对象),索引按目录 mtime 失效;同时为规避 fork 后子进程复用父进程打开 zip 句柄引发 BadZipFile/OSError,通过 os.register_at_fork(after_in_child=cache_clear) 在 fork 后清空缓存(_clear_after_fork,第 804–816 行);
  • PathDistribution(第 1012–1064 行)是默认的具体 Distributionread_textFileNotFoundErrorIsADirectoryErrorKeyErrorNotADirectoryErrorPermissionError 等一律抑制并返回 Nonelocate_file 返回元数据目录父级下的 SimplePath;其规范化名优先从目录名(去掉 .dist-info/.egg-info 后缀及 -版本 部分)直接推断,省去读取 METADATA

zip 支持方面,FastPath.children()os.listdir 失败后回退到 zip_children()——用 zipfile.Path 打开归档、提取其顶层条目(第 852–860 行)。仓库中的 Lib/test/test_importlib/metadata/test_zip.py 专门覆盖 zip 归档场景,Lib/test/test_importlib/metadata/test_main.pyLib/test/test_importlib/metadata/test_api.py 覆盖函数式 API 与 Distribution 类的行为,可作为你验证上述语义的权威测试参考。

实现自定义 Provider:从数据库提供元数据

importlib.metadata 面向两类 API 使用者:消费者(绝大多数用户)与提供者。若你希望从自定义导入器等额外机制暴露元数据,就需要实现自定义 Provider。由于发行包元数据无法仅靠 sys.path 搜索或包加载器直接获得,模块通过导入系统 finder 来发现元数据:查询 sys.meta_path 上的 meta path finders 是否带有 find_distributions。CPython 把这一钩子内建到了 PathFinder 中,为文件系统上的发行包提供元数据。

importlib.abc.MetaPathFinder 定义了 Python 导入系统期望 finder 具备的接口;importlib.metadata 通过寻找 finder 上可选的 find_distributions 可调用对象扩展该协议,并把它呈现为 DistributionFinder 抽象基类。其抽象方法签名为:

@abc.abstractmethod
def find_distributions(context=DistributionFinder.Context()) -> Iterable[Distribution]:
    """Return an iterable of all Distribution instances capable of
    loading the metadata for packages for the indicated ``context``.
    """

DistributionFinder.Context 对象提供 path(要搜索的路径)与 name(要匹配的名字)属性,也可携带消费者所需的其他上下文。实践中的做法是:先继承 Distribution 并实现其抽象方法,然后在自定义 finder 的 find_distributions() 中返回这些派生 Distribution 的实例。

完整示例:数据库驱动的模块与元数据

文档给出的示例场景是——自定义 finder 从数据库加载 Python 模块:

class DatabaseImporter(importlib.abc.MetaPathFinder):
    def __init__(self, db):
        self.db = db

    def find_spec(self, fullname, target=None) -> ModuleSpec:
        return self.db.spec_from_name(fullname)

sys.meta_path.append(DatabaseImporter(connect_db(...)))

这个 importer 能提供可从数据库导入的模块,却没有任何元数据或入口点。要让它提供元数据,需同时实现 DistributionFinder

from importlib.metadata import DistributionFinder

class DatabaseImporter(DistributionFinder):
    ...

    def find_distributions(self, context=DistributionFinder.Context()):
        query = dict(name=context.name) if context.name else {}
        for dist_record in self.db.query_distributions(query):
            yield DatabaseDistribution(dist_record)

如此,query_distributions 就会为数据库中与查询匹配的每个发行包返回记录。例如数据库中存有 requests-1.0,则对 Context(name='requests')Context(name=None)find_distributions 调用都会产出对应的 DatabaseDistribution

为简洁起见,该示例忽略了 context.pathpath 默认是 sys.path,指搜索时应考虑的导入路径集合。DatabaseImporter 若无分区需求(行为不随 sys.path/PYTHONPATH 变化),path 确实无关紧要;反之,find_distributions 就应尊重 context.path,只产出与该路径相关的 Distribution

DatabaseDistribution 的实现大致如下:

class DatabaseDistribution(importlib.metadata.Distribution):
    def __init__(self, record):
        self.record = record

    def read_text(self, filename):
        """
        Read a file like "METADATA" for the current distribution.
        """
        if filename == "METADATA":
            return f"""Name: {self.record.name}
Version: {self.record.version}
"""
        if filename == "entry_points.txt":
            return "\n".join(
              f"""[{ep.group}]\n{ep.name}={ep.value}"""
              for ep in self.record.entry_points)

    def locate_file(self, path):
        raise RuntimeError("This distribution has no file system")

只要 record 提供了合适的 .name.version.entry_points 属性,这个基础实现即可为数据库服务的包提供元数据与入口点。它还可以进一步提供 RECORD 等文件(这是 Distribution.files 所需的),或直接覆写 Distribution.files 的实现——前者可从源码 Distribution.read_text 的 docstring 与 files 的实现逻辑中获得启发。仓库中完整可运行的测试基础设施(如 Lib/test/test_importlib/metadata/fixtures.py)也展示了如何搭建自定义元数据源来驱动 importlib.metadata 的各类场景。

结语与进一步阅读

importlib.metadata 以一套简洁的函数式 API 加上一个可扩展的 Distribution / DistributionFinder 抽象层,为「读取已安装发行包的元数据」这一任务提供了标准答案:version()metadata()entry_points()files()requires()packages_distributions() 覆盖绝大多数查询需求;Distribution 类提供对等且更细粒度的对象式访问;而 DistributionFinder + 自定义 Distribution 子类则让元数据源不局限于文件系统与 zip 归档。它的默认发现实现(PathDistributionMetadataPathFinderPrepared 名字归一化与 FastPath 缓存)与配套测试都位于 Lib/importlib/metadata/Lib/test/test_importlib/metadata/ 目录下,是深入研读实现的起点。若你需要覆盖到较早的 Python 版本,可考虑使用与标准库共享同一实现的 importlib_metadata backport(其文档还包含本模块 API reference 与面向 pkg_resources 用户的迁移指南)。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.74 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.81 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
595
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
920
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.63 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
518
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
389