如何用Python检查系统中是否安装某个包?

1 投票
2 回答
3821 浏览
提问于 2025-04-18 14:38

我怎么能检查我的系统上是否安装了某个软件包呢?我的系统是Linux,不过如果能在其他操作系统上也能用就更好了。我指的是特定于操作系统的软件包,比如*.rpm或*.deb这样的。

有没有什么Python模块或者脚本可以做到这一点呢?

2 个回答

3

“包”这个词有好几种相似但不兼容的意思,不过你提到“包或模块”,这说明你想了解的是Python中的包和模块,也就是那些可以用import引入的东西。

如果是这样,测试的方法就是用import来尝试引入它们。

手动操作的话,可以这样做:

$ python
>>> import foo
ImportError: No module named foo

嗯,foo没有安装。

如果想用程序来测试:

try:
    import foo
except ImportError:
    # do whatever you wanted if foo is missing

注意,这并不能告诉你foo缺失,只是说它无法被引入。在一个简单的“测试你是否拥有这个”的脚本中,这通常是你想要检查的内容。但是,如果你真的想检查“是否安装(即使是坏的)”呢?

在最近的Python版本中(我想是3.4及以上),ImportError会包含额外的信息,你可以访问这些信息——比如你尝试引入的名称name,如果找到了还会有path等信息。不过,这种情况下,EAFP(“先尝试后验证”)可能不如LBYL(“先验证后尝试”)更好。你可以使用importlib来搜索模块,而不尝试引入它,像这样:

spec = importlib.util.find_spec('foo')

如果你使用的是旧版Python呢?从3.2开始有类似的功能,但没有那么好用。如果你在用2.7,实际上没有什么值得使用的,因为引入机制并没有很好地暴露出来。

在这种情况下(以及许多与包安装相关的其他酷东西),可以使用setuptools——这不是标准库的一部分,但很多第三方包都依赖它(直到最近,它一直是Python包安装的基石,尽管不是官方的):

pkg_resources.get_distribution('foo')

不过,这个是查找distutils/setuptools/PyPI包,而不是Python模块或包。虽然这两者有很多重叠,但并不完全相同。举个简单的例子,当你用pip install more-itertools时,你得到的是more-itertools这个PyPI包,它会把more_itertools这个Python包安装到你的site-packages目录里。

4

要查看你是否安装了 .deb、.rpm 等格式的软件包,你需要使用适合你系统的软件包管理工具。

在 Debian 系统中,有一个叫 python-apt 的 Python 工具,或者你也可以在 PyPI 上找到一个叫 apt 的库。

对于 RPM 格式,有很多 Python 工具。实际上,Redhat 的安装系统大部分都是用 Python 写的,你应该已经安装了 rpm 模块。在你寻找更高级的工具之前,建议先看看 用 Python 编程 RPM(或者更好的是,搜索一个更新的版本),这样你能理解自己在做什么;即使是使用低级接口,代码也只有几行而已。

据我所知,目前还没有一个通用的工具可以处理所有 Linux 发行版使用的各种软件包格式和数据库(即使有,也不一定适用于那些不使用软件包管理系统的 Linux 系统)。不过,如果你只想处理一些常见的系统,使用 python-apt 和 Redhat 自己的工具,或者在 PyPI 上搜索 RPM,就能覆盖你关心的大部分内容。

另外,pkg-config 是最接近“这个系统上安装的软件包”的通用工具。每个 Linux 系统都会有它(大多数其他非 Windows 系统也有),但并不是每个软件包都会在 pkg-config 中注册。不过,如果你在找这个,pkgconfig 是 Python 的解决方案。

撰写回答