Check if Python Package is installed

前端 未结 16 1037
刺人心
刺人心 2020-12-02 05:59

What\'s a good way to check if a package is installed while within a Python script? I know it\'s easy from the interpreter, but I need to do it within a script.

I g

相关标签:
16条回答
  • 2020-12-02 06:34

    A quick way is to use python command line tool. Simply type import <your module name> You see an error if module is missing.

    $ python
    Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
    >>> import sys
    >>> import jocker
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ImportError: No module named jocker
    $
    
    0 讨论(0)
  • 2020-12-02 06:34

    I would like to comment to @ice.nicer reply but I cannot, so ... My observations is that packages with dashes are saved with underscores, not only with dots as pointed out by @dwich comment

    For example, you do pip3 install sphinx-rtd-theme, but:

    • importlib.util.find_spec(sphinx_rtd_theme) returns an Object
    • importlib.util.find_spec(sphinx-rtd-theme) returns None
    • importlib.util.find_spec(sphinx.rtd.theme) raises ModuleNotFoundError

    Moreover, some names are totally changed. For example, you do pip3 install pyyaml but it is saved simply as yaml

    I am using python3.8

    0 讨论(0)
  • 2020-12-02 06:34

    Go option #2. If ImportError is thrown, then the package is not installed (or not in sys.path).

    0 讨论(0)
  • 2020-12-02 06:35

    Updated answer

    A better way of doing this is:

    import subprocess
    import sys
    
    reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
    installed_packages = [r.decode().split('==')[0] for r in reqs.split()]
    

    The result:

    print(installed_packages)
    
    [
        "Django",
        "six",
        "requests",
    ]
    

    Check if requests is installed:

    if 'requests' in installed_packages:
        # Do something
    

    Why this way? Sometimes you have app name collisions. Importing from the app namespace doesn't give you the full picture of what's installed on the system.

    Note, that proposed solution works:

    • When using pip to install from PyPI or from any other alternative source (like pip install http://some.site/package-name.zip or any other archive type).
    • When installing manually using python setup.py install.
    • When installing from system repositories, like sudo apt install python-requests.

    Cases when it might not work:

    • When installing in development mode, like python setup.py develop.
    • When installing in development mode, like pip install -e /path/to/package/source/.

    Old answer

    A better way of doing this is:

    import pip
    installed_packages = pip.get_installed_distributions()
    

    For pip>=10.x use:

    from pip._internal.utils.misc import get_installed_distributions
    

    Why this way? Sometimes you have app name collisions. Importing from the app namespace doesn't give you the full picture of what's installed on the system.

    As a result, you get a list of pkg_resources.Distribution objects. See the following as an example:

    print installed_packages
    [
        "Django 1.6.4 (/path-to-your-env/lib/python2.7/site-packages)",
        "six 1.6.1 (/path-to-your-env/lib/python2.7/site-packages)",
        "requests 2.5.0 (/path-to-your-env/lib/python2.7/site-packages)",
    ]
    

    Make a list of it:

    flat_installed_packages = [package.project_name for package in installed_packages]
    
    [
        "Django",
        "six",
        "requests",
    ]
    

    Check if requests is installed:

    if 'requests' in flat_installed_packages:
        # Do something
    
    0 讨论(0)
提交回复
热议问题