pkg_resources: 获取自己的分发版本?

5 投票
1 回答
3594 浏览
提问于 2025-04-17 23:39

我想要找到一个文件的分发信息。这个文件应该能够自己发现它的分发信息。

我试过这样做,但没有成功:

import os
import pkg_resources
for dist in pkg_resources.find_distributions(os.path.dirname(__file__)):
    print dist

上面提到的文件是通过 pip install -e ... 安装的。

我在文档里找不到解决办法:

https://pythonhosted.org/setuptools/pkg_resources.html#distribution-objects

这个解决方案不应该包含包的字符串,它应该是通用的。

1 个回答

10

pkg_resources这个工具需要一个发行名称; 这个名称不一定和当前模块使用的包名称相同。

举个例子,BeautifulSoup这个项目。现在的版本使用bs4作为包名称,但在PyPI上的发行名称beautifulsoup4

一个发行可以包含多个顶级包或模块;比如说,pkg_resources模块本身就是setuptools这个发行的一部分,和setuptools包一起。

所以,你不能简单地使用__file____package__来总是找到对应的发行。

如果你的发行是以egg的形式安装的(比如用easy_installzc.buildout),那么你可以在路径中查找.egg扩展名,找到那个位置后分割路径,然后使用Distribution.from_filename()来生成一个Distribution对象;文件名里包含了所有必要的信息。但是如果你的包是用pip安装的,系统会创建一个单独的.egg-info文件,这样你又回到了原点(找不到发行名称)。

另外,你可以通过pkg_resources.Environment()实例获取你环境中的所有Distribution对象;但你会遇到同样的问题,无法将现有的发行与某个模块或包匹配,至少在公共API中是这样。你可以扫描所有发行,结合.location属性(针对egg)和可能存在的(私有的)Distribution._provider属性,以及(完全可选的)installed-files.txt元数据条目(如果存在,里面包含相对路径(!)),这样你就可以扫描整个环境来寻找匹配的发行,但这完全依赖于各种资源提供者的内部实现细节。而且对于较大的安装来说,这可能会是一个耗时的搜索。

因此,最好的选择就是直接使用一个硬编码的发行名称。

撰写回答