有python脚本检查缺少的模块和安装,如果缺少

时间:2018-03-05 18:24:06

标签: python

我正在寻找一个我写得更便携的脚本。

我的脚本中使用的一些工具要求安装某些模块。我已经能够让脚本自己安装模块,但是希望有一种机制来检查它们是否已经安装,并且只在缺少时尝试安装。

我确信这是可能的,但我似乎无法找到解决方案。

3 个答案:

答案 0 :(得分:2)

标准解决方案是将您的脚本变为模块,declare its dependencies in the setup.py of the module.

from setuptools import setup

setup(name='foo',
  ...
  install_requires=['dependency', 'other', ...])

支持性较弱的惯例是将列表保留在requirements.txt中,以便

pip install -r requirements.txt

拥有自己的脚本做这些家务通常不是有用的或必要的;现有的打包基础架构已经提供了您所需要的,并且是操纵和管理包依赖关系的自然要点。

从历史上看,由于不同的打包方式在Python生态系统中争夺主导地位,因此存在一些动荡,但现在似乎已经在setuptoolspip上找到了很多东西。

答案 1 :(得分:1)

你可以试试这个:

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

try:
    import your_module
except ImportError:
    print 'Module not installed'
    install('your_module')

答案 2 :(得分:0)

通常,代表运行脚本的人下载和安装内容并不好。正如三人的答案所提到的那样,使用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'