如何在Python中检查模块是否已安装,如果没有安装,则在代码中安装它?

70

我想为我的代码安装'mutagen'和'gTTS'模块,但我希望它能在每台没有这些模块的计算机上安装它们,但如果它们已经安装了,就不要尝试安装它们。 我目前有:

def install(package):
    pip.main(['install', package])

install('mutagen')

install('gTTS')

from gtts import gTTS
from mutagen.mp3 import MP3

然而,如果您已经拥有这些模块,每次打开程序时它们只会增加不必要的混乱。


你需要一个Python脚本来运行执行安装检查和安装的命令吗?还是你只是想在所有这些“计算机”上执行shell命令? - JacobIRR
4
尽管你可以从脚本内部技术上强制安装模块,但不要这样做,这是一种不好的实践方式,如果你这样做,人们肯定会讨厌你。相反,学习如何正确地打包和分发你的Python应用程序:https://www.digitalocean.com/community/tutorials/how-to-package-and-distribute-python-applications - zwer
@zwer 是正确的。不要这样做。如果你的包有依赖关系,让 pip 处理它们。 - Christian Dean
可能是重复问题:检查Python包是否已安装 - Herpes Free Engineer
12个回答

86

编辑 - 2020/02/03

自我发布这个答案以来,pip模块已经更新了很多。 我已经更新了片段,以使用正确的方法安装缺少的依赖项,即使用subprocesspkg_resources,而不是pip

要隐藏输出,您可以将子进程输出重定向到devnull:

import sys
import subprocess
import pkg_resources

required = {'mutagen', 'gTTS'}
installed = {pkg.key for pkg in pkg_resources.working_set}
missing = required - installed

if missing:
    python = sys.executable
    subprocess.check_call([python, '-m', 'pip', 'install', *missing], stdout=subprocess.DEVNULL)

就像 @zwer 提到的那样,上面的方法是可行的,但并不被视为打包项目的正确方式。要更深入地了解这个问题,请阅读页面如何打包Python应用程序


17
请添加一份免责声明,说明当有人在他们的代码中使用 import pip 作为适当打包方法的绕过方式时,会导致一只小猫死亡。-_- - zwer
@TheGirrafish,我在搜索中也找到了这段代码,大约5分钟前。XD 谢谢你的帮助。 - Foxes
1
@TheGirrafish 抱歉,我的意思是列表由 pip 库的 "EggInfoDistribution"(以及 DistINfoDistribution)组成。例如,在我的情况下,列表中的第一项是 "xmltodict 0.10.2",但是 "xmltodict 0.10.2" in pip.get_installed_distributions() 返回 False,而 "xmltodict 0.10.2" in str(pip.get_installed_distributions()) 返回 True。 - aoh
1
@dcoles 感谢您提出这个问题,我已经更改了代码段,使用subprocess替换了pip - Girrafish
3
与其使用重定向sys.stdout,我建议使用subprocess.check_call(args, stdout=subprocess.DEVNULL)忽略pip的stdout。 - dcoles
显示剩余9条评论

40

您可以使用简单的try/except:

try:
    import mutagen
    print("module 'mutagen' is installed")
except ModuleNotFoundError:
    print("module 'mutagen' is not installed")
    # or
    install("mutagen") # the install function from the question


29
如果你想知道一个软件包是否已安装,可以在终端中使用以下命令检查:
pip list | grep <module_name_you_want_to_check>

如何运作:

pip list

列出您的Python中安装的所有模块。

竖线|通常称为“管道”。它用于将一个命令导入另一个命令。也就是说,它将第一个命令的输出指向第二个命令的输入。

grep <module_name_you_want_to_check>

从列表中查找关键字。

示例:


pip list| grep quant

列出所有以"quant"开头的包(例如"quantstrats")。如果没有任何输出,则表示该库未安装。


2
请添加一些描述,而不仅仅是代码块。 - live2
这完全不是答案,因为问题还在询问如何通过代码安装。 - papiro
“start with” 在技术上应该是 “contains” … 使用 grep "\wquant" 或 grep "^quant" 会更准确一些。在 Windows 上,我还需要使用 grep -E 来支持扩展正则表达式。 - aschultz
这不是一个指出如何使用Python代码找到包是否已安装的答案。这个答案使用了一个命令,因此需要用户交互。 - Andrew

9
你可以使用pkg_resources.get_distribution来检查一个软件包是否已经安装:
import pkg_resources

for package in ['mutagen', 'gTTS']:
    try:
        dist = pkg_resources.get_distribution(package)
        print('{} ({}) is installed'.format(dist.key, dist.version))
    except pkg_resources.DistributionNotFound:
        print('{} is NOT installed'.format(package))

注意: 不应直接导入pip模块,因为这是pip命令的不支持用法之一,请勿这样做。

从程序中使用pip 推荐方法是使用subprocess执行它:

subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'my_package'])

由于某种原因,这种方法比使用“working_set”慢了大约1400倍。 - Mandera

4
对于Python 3.3及以上版本,请使用以下代码:
import importlib
spec = importlib.util.find_spec('some_module')
if spec is not None:
    print('module is installed')

3
虽然 @girrafish 的回答可能足够了,但你也可以通过 importlib 来检查软件包的安装。
import importlib

packages = ['mutagen', 'gTTS']
[subprocess.check_call([sys.executable, '-m', 'pip', 'install', pkg]) 
for pkg in packages if not importlib.metadata.distribution(pkg)]

1
[subprocess.check_call([sys.executable, '-m', 'pip', 'install', pkg, '-q']) for pkg in ['datasets'] if not importlib.util.find_spec(pkg)]sys.executable 应该使用 Python 可执行文件,同时添加了 -q 参数以避免输出。非常简洁明了的答案。 - Prox

2
您可以使用命令行:
python -m MyModule

如果模块存在,则会提示出来。

否则,您可以简单地使用最佳实践:

pip freeze > requirements.txt

这将把您在 python 安装中的模块放入一个文件中。

然后:

pip install -r requirements.txt

来加载它们。

它将自动帮助您完成目的。

祝玩得开心!


1
另一个解决方案是将你想要导入的内容放在try/except块中的import语句中,这样如果它被安装了就可以工作,但如果没有安装它会抛出异常,然后你可以运行命令来安装它。

1
你可以运行pip show package_name来查看具体信息,或者使用pip list来查看所有信息。参考资料

0

如果您想预览特定软件包(或某些软件包)是否已安装,也许可以使用Python中的IDLE。

  1. 打开IDLE
  2. 浏览到文件 > 打开模块 > 某个模块
  3. IDLE将显示该模块或提示错误消息。

以上内容已在Python 3.9.0中进行了测试。


1
我认为这个问题的意思是,Python代码将在每台运行它的计算机上安装模块。 - matan h

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接