从包中获取 Python 包分发版本 [英] Getting Python package distribution version from within a package
问题描述
您可以使用
import pkg_resources
pkg_resources.get_distribution("distro").version
如果您知道发行版名称,那就太好了,但是我需要在运行时动态找出我的发行版名称.
This is great if you know the distribution name, however I need to dynamically figure out my distribution name at runtime.
# Common framework base app class, extended by each app
class App(object):
def get_app_version(self) -> str:
package_name = self.__class__.__module__.split('.')[0]
try:
return pkg_resources.get_distribution(package_name).version
except Exception:
return "development"
这适用于应用程序包名称与分发名称相同的情况(例如 requests
).但是,一旦它们不匹配(例如 my-app
包含包 my_app
),这就会失败.
This works for cases where the app's package name is the same as the distribution name (e.g. requests
). However this fails once they don't match (e.g. my-app
containing package my_app
).
所以我需要的是发行版和它们的包之间的映射,我确定它一定存在于某个地方,因为 pip 似乎知道在您调用卸载时要删除的内容:
So what I need is a mapping between distributions and their packages, which I'm sure must exist somewhere since pip seems to know what to delete when you call uninstall:
$ pip uninstall requests
Uninstalling requests-2.21.0:
Would remove:
/home/user/.virtualenvs/app/lib/python3.6/site-packages/requests-2.21.0.dist-info/*
/home/user/.virtualenvs/app/lib/python3.6/site-packages/requests/*
如何以编程方式访问此映射?
How do I programatically access this mapping?
推荐答案
我认为项目名称应该尽可能硬编码.如果没有,那么像下面这样的一些函数可以帮助找出包含当前文件(__file__
)的已安装发行版的元数据:
I believe the project's name should be hard-coded if possible. If not then some function like the following could help figuring out the metadata for the installed distribution containing the current file (__file__
):
import pathlib
import importlib_metadata
def get_project_distribution():
for dist in importlib_metadata.distributions():
try:
relative = pathlib.Path(__file__).relative_to(dist.locate_file(''))
except ValueError:
pass
else:
if relative in dist.files:
return dist
return None
project_distribution = get_project_distribution()
if project_distribution:
project_name = project_distribution.metadata['Name']
version = project_distribution.metadata['Version']
更新(2021 年 2 月):
Update (February 2021):
由于 importlib_metadata
中新添加的 packages_distributions()
函数,看起来这会变得更容易:
Looks like this could become easier thanks to the newly added packages_distributions()
function in importlib_metadata
:
- https://importlib-metadata.readthedocs.io/en/stable/using.html#package-distributions
- https://github.com/python/importlib_metadata/pull/287/files
这篇关于从包中获取 Python 包分发版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!