【问题标题】:How to check if a module is installed in Python and, if not, install it within the code?如何检查模块是否安装在 Python 中,如果没有,则将其安装在代码中?
【发布时间】:2017-10-27 21:12:33
【问题描述】:

我想为我的代码安装模块“mutagen”和“gTTS”,但我想拥有它,以便它会在每台没有它们的计算机上安装这些模块,但它不会尝试如果它们已经安装,请安装它们。我目前有:

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

install('mutagen')

install('gTTS')

from gtts import gTTS
from mutagen.mp3 import MP3

但是,如果您已经有了这些模块,这只会在您打开程序时给程序的开头添加不必要的混乱。

【问题讨论】:

  • 你想要一个python脚本来运行执行安装检查和安装的命令吗?或者你可以在所有这些“计算机”上执行 shell 命令吗?
  • 虽然从技术上讲,您可以从脚本中强制安装模块,但不要这样做,这是一种不好的做法,如果您这样做,人们将不可避免地讨厌您。相反,学习如何正确打包和分发您的 Python 应用程序:digitalocean.com/community/tutorials/…
  • @zwer 是正确的。不要这样做。如果你的包有依赖,让pip处理。

标签: python python-3.x module python-module


【解决方案1】:

你可以使用简单的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

【讨论】:

    【解决方案2】:

    虽然@girrafish 的回答可能就足够了,但您也可以通过importlib 检查软件包安装情况:

    import importlib
    
    packages = ['mutagen', 'gTTS']
    [subprocess.check_call(['pip', 'install', pkg]) 
    for pkg in packages if not importlib.util.find_spec(pkg)]
    

    【讨论】:

      【解决方案3】:

      你可以运行pip show package_name 或为了广阔的视野use pip list Reference

      【讨论】:

        【解决方案4】:

        如果你想知道一个包是否被安装,你可以在你的终端中使用以下命令来检查它:

        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”)。如果您没有任何输出,则表示该库未安装。

        【讨论】:

        • 请添加一些说明,而不仅仅是代码块
        • 这完全不是答案,因为问题也是在询问如何安装,并从代码中完成所有这些......
        • "start with" 在技术上应该是 "contains" ... grep "\wquant" 或 grep "^quant" 会更准确。在 Windows 上,我还需要 grep -E 来扩展正则表达式。
        【解决方案5】:

        如果您想预览是否安装了特定包(或某些包),您可以使用 python 中的空闲。 具体来说:

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

        以上是用python 3.9.0测试的

        【讨论】:

        • 我认为这个问题意味着 Python 代码将在每台运行它的计算机上安装模块
        【解决方案6】:

        编辑 - 2020/02/03

        自从我发布这个答案以来,pip 模块已经更新了很多。我已经用正确的方法更新了 sn-p 以安装缺少的依赖项,即使用 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 提到的那样,上述方法有效,尽管它不被视为打包项目的正确方式。要更深入地了解这一点,请阅读页面How to package a Python App

        【讨论】:

        • 这很好用,但是它给出了“要求已经满足”的输出,当你打开它时,在代码的开头添加了不必要的混乱。有没有办法让它不回应“已经满足的要求”?
        • 请添加免责声明,只要有人在其代码中使用import pip 作为正确包装的解决方法,小猫就会死亡。 -_-
        • @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
        • @dcoles 感谢您提出这个问题,我已将代码 sn-p 更改为使用 subprocess 而不是 pip
        • 另外,而不是使用而不是重定向sys.stdout,我建议只使用subprocess.check_call(args, stdout=subprocess.DEVNULL) 来忽略pip 的标准输出。
        【解决方案7】:

        您可以使用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 命令的it is an unsupported use-case 导入。

        recommended way of using pip from your program 是使用subprocess 执行它:

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

        【讨论】:

          【解决方案8】:

          另一种解决方案是将您尝试导入的任何内容放入 try/except 块中的导入语句,因此如果它有效,则已安装,但如果无效,它将抛出异常,您可以运行命令进行安装它。

          【讨论】:

            【解决方案9】:

            你可以使用命令行:

            python -m MyModule
            

            它会说模块是否存在

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

            pip freeze > requirements.txt

            这会将你在 python 安装中的模块放在一个文件中

            和:

            pip install -r requirements.txt

            加载它们

            它会自动你的目的

            玩得开心

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-10-21
              • 1970-01-01
              • 2017-01-27
              • 2022-11-23
              • 1970-01-01
              • 2012-09-02
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多