使用Python检查系统中是否安装了某个软件包?

14 浏览
0 Comments

使用Python检查系统中是否安装了某个软件包?

我该如何检查系统中是否安装了某个软件包?我的系统是Linux,如果能在其他操作系统上运行就更好了。我指的是特定于操作系统的软件包(例如*.rpm或*.deb)。

是否有任何可以执行此操作的Python模块或脚本?

0
0 Comments

问题的出现原因是要判断系统是否安装了某个软件包,需要根据不同的软件包管理系统使用相应的工具进行判断。APT包管理系统在Debian中有一个名为python-apt的Python包装器,在PyPI上有apt包。RPM包管理系统有一整套的Python工具,实际上Redhat的安装程序生态系统大部分是基于Python构建的,你应该已经安装了rpm模块。在寻找高级封装器之前,先阅读《Programming RPM with Python》(或者更好的是搜索更新的版本),以便理解你实际上在做什么;即使使用低级接口,只需要几行代码就可以实现。据我所知,没有人将这些封装成一个通用工具,可以适用于每个Linux发行版使用的所有软件包格式和数据库(即使有,对于不使用软件包管理系统的Linux系统也没有多大用处)。但是,如果你只想处理一些流行的系统,使用python-apt和Redhat自己的工具,或者在PyPI上搜索RPM包,这几乎可以涵盖你关心的一切。另外,pkg-config是最接近于"此系统上安装的软件包"的通用概念。每个Linux系统都会有它(以及大多数其他非Windows系统),但并不是每个软件包都会在pkg-config中注册。但是,如果这是你要寻找的,pkgconfig是Python的答案。

0
0 Comments

如何使用Python检查系统中是否安装了一个软件包?

单词“package”有六种类似但不兼容的含义,但是你提到“包或模块”暗示你特别想知道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中。

要检查Python模块的可用性,应该使用pkg_resources.get_distribution('foo')并捕获DistributionNotFound,而不是捕获ImportError,以免隐藏循环依赖。

import也可能有其他问题,但对于快速检查,它告诉你是否可以导入模块(一个简单的测试脚本不会有循环依赖 - 除非模块本身有循环依赖,这样你就无法导入它,所以这是正确的答案)。pkg_resourcessetuptools的一部分,是我之前提到的那些“高级东西”之一,但也许我应该在答案中扩展一下。

我同意,这是一个更高级的细节 - 所以还是+1 ;-)但它是正确的API,并且回答了OP提出的确切问题:模块XY是否已安装?是否可以使用是一个稍微不同的问题,一个人可能希望让错误显示出来。

嗯,它是setuptools安装的正确API;它是一个hacky-and-not-official-but-thoroughly-reliable API,适用于以任何其他方式安装的软件包(除了distribute或本地3.4+的pip)。但是,更重要的是,这是distutils软件包的API,而不是模块和软件包的API。除非一个distutils软件包包含与自身同名的一个模块或软件包,否则你得到的答案是错误的。

是的,我的措辞“Python模块的可用性”是不正确的 - 我应该说“基于setuptools的分发”。所以如果你对ImageOps模块感兴趣,你显然需要检查PIL分发(或者说Pillow)。

当然,结果是,“模块和软件包”既不是指“Python模块和软件包”,也不是指“distutils/PyPA分发”,所以我们在这里都谈到了错误的东西。

0