如何用Python检查系统中是否安装某个包?
我怎么能检查我的系统上是否安装了某个软件包呢?我的系统是Linux,不过如果能在其他操作系统上也能用就更好了。我指的是特定于操作系统的软件包,比如*.rpm或*.deb这样的。
有没有什么Python模块或者脚本可以做到这一点呢?
2 个回答
“包”这个词有好几种相似但不兼容的意思,不过你提到“包或模块”,这说明你想了解的是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目录里。
要查看你是否安装了 .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 的解决方案。