让python脚本检查缺少的模块,如果缺少则安装

让python脚本检查缺少的模块,如果缺少则安装,python,Python,我正在努力使我写的脚本更具可移植性 我的脚本中使用的一些工具需要安装某些模块。我已经能够让脚本自己安装模块,但希望有一个机制,可以检查它们是否已经安装,只有在丢失时才尝试安装 我相信这是可能的,但我似乎找不到解决方案。您可以尝试以下方法: 您可以尝试以下方法: 标准的解决方案是将脚本制作成一个模块 一个支持性较弱的约定是在requirements.txt中保留一个列表,以便 pip install -r requirements.txt 让你自己的脚本来做这些杂务通常是没有用处或必要的;现有的

我正在努力使我写的脚本更具可移植性

我的脚本中使用的一些工具需要安装某些模块。我已经能够让脚本自己安装模块,但希望有一个机制,可以检查它们是否已经安装,只有在丢失时才尝试安装

我相信这是可能的,但我似乎找不到解决方案。

您可以尝试以下方法:

您可以尝试以下方法:


标准的解决方案是将脚本制作成一个模块

一个支持性较弱的约定是在requirements.txt中保留一个列表,以便

pip install -r requirements.txt
让你自己的脚本来做这些杂务通常是没有用处或必要的;现有的打包基础设施已经提供了您所需要的,并且是操作和管理包依赖关系的自然点


从历史上看,由于不同的打包机制在Python生态系统中争夺主导地位,因此出现了一些混乱,但现在事情似乎已经基本解决了setuptools和pip问题。

解决这一问题的标准解决方案是将脚本制作成一个模块,然后

一个支持性较弱的约定是在requirements.txt中保留一个列表,以便

pip install -r requirements.txt
让你自己的脚本来做这些杂务通常是没有用处或必要的;现有的打包基础设施已经提供了您所需要的,并且是操作和管理包依赖关系的自然点


从历史上看,由于不同的打包机制在Python生态系统中争夺主导地位,因此出现了一些混乱,但现在似乎基本上解决了setuptools和pip问题。

通常,代表运行脚本的人下载和安装东西并不好。正如triplee的回答所提到的,使用requirements.txt和适当的setup.py是一种标准且更好的做法

无论如何,下面是一个在脚本中获得所需行为的黑客程序

import pip
import importlib
modules = ['requests', 'fake_module_name_that_does_not_exist']
for modname in modules:
    try:
        # try to import the module normally and put it in globals
        globals()[modname] = importlib.import_module(modname)
    except ImportError as e:
        result = pip.main(['install', modname])
        if result != 0: # if pip could not install it reraise the error
            raise
        else:
            # if the install was sucessful, put modname in globals
            globals()[modname] = importlib.import_module(modname)
如果执行这个示例,您将得到如下输出

Collecting requests
  Using cached requests-2.18.4-py2.py3-none-any.whl
Requirement already satisfied: idna<2.7,>=2.5 in c:\users\spenceryoung\envs\test_venv\lib\site-packages (from requests)
Requirement already satisfied: urllib3<1.23,>=1.21.1 in c:\users\spenceryoung\envs\test_venv\lib\site-packages (from requests)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in c:\users\spenceryoung\envs\test_venv\lib\site-packages (from requests)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\spenceryoung\envs\test_venv\lib\site-packages (from requests)
Installing collected packages: requests
Successfully installed requests-2.18.4
Collecting fake_module_name_that_does_not_exist
  Could not find a version that satisfies the requirement fake_module_name_that_does_not_exist (from versions: )
No matching distribution found for fake_module_name_that_does_not_exist
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
  File "C:\Users\spenceryoung\AppData\Local\Programs\Python\Python36-32\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'fake_module_name_that_does_not_exist'

通常,代表运行脚本的人下载和安装东西是不好的。正如triplee的回答所提到的,使用requirements.txt和适当的setup.py是一种标准且更好的做法

无论如何,下面是一个在脚本中获得所需行为的黑客程序

import pip
import importlib
modules = ['requests', 'fake_module_name_that_does_not_exist']
for modname in modules:
    try:
        # try to import the module normally and put it in globals
        globals()[modname] = importlib.import_module(modname)
    except ImportError as e:
        result = pip.main(['install', modname])
        if result != 0: # if pip could not install it reraise the error
            raise
        else:
            # if the install was sucessful, put modname in globals
            globals()[modname] = importlib.import_module(modname)
如果执行这个示例,您将得到如下输出

Collecting requests
  Using cached requests-2.18.4-py2.py3-none-any.whl
Requirement already satisfied: idna<2.7,>=2.5 in c:\users\spenceryoung\envs\test_venv\lib\site-packages (from requests)
Requirement already satisfied: urllib3<1.23,>=1.21.1 in c:\users\spenceryoung\envs\test_venv\lib\site-packages (from requests)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in c:\users\spenceryoung\envs\test_venv\lib\site-packages (from requests)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\spenceryoung\envs\test_venv\lib\site-packages (from requests)
Installing collected packages: requests
Successfully installed requests-2.18.4
Collecting fake_module_name_that_does_not_exist
  Could not find a version that satisfies the requirement fake_module_name_that_does_not_exist (from versions: )
No matching distribution found for fake_module_name_that_does_not_exist
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
  File "C:\Users\spenceryoung\AppData\Local\Programs\Python\Python36-32\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'fake_module_name_that_does_not_exist'

你已经拥有的任何例子都会很好。你已经拥有的任何例子的可能重复都会很好。可能重复的关于替代品的更多信息,请查看,例如,关于替代品的更多信息,请查看。例如,感谢你提供了一个适合我尝试实现的选项,即使这不是最佳实践。我现在知道该往哪个方向看了。谢谢你提供了一个适合我的选择,即使这不是最佳实践。我现在知道该往哪个方向看了。