144

在 Python 脚本中检查是否安装了包的好方法是什么?我知道解释器很容易,但我需要在脚本中完成。

我想我可以检查系统上是否有在安装过程中创建的目录,但我觉得有更好的方法。我正在尝试确保已安装 Skype4Py 软件包,如果没有,我将安装它。

我完成检查的想法

  • 检查典型安装路径中的目录
  • 尝试导入包,如果抛出异常,则安装包
4

18 回答 18

136

如果您的意思是 python 脚本,只需执行以下操作:

Python 3.3+ 使用 sys.modules 和find_spec

import importlib.util
import sys

# For illustrative purposes.
name = 'itertools'

if name in sys.modules:
    print(f"{name!r} already in sys.modules")
elif (spec := importlib.util.find_spec(name)) is not None:
    # If you choose to perform the actual import ...
    module = importlib.util.module_from_spec(spec)
    sys.modules[name] = module
    spec.loader.exec_module(module)
    print(f"{name!r} has been imported")
else:
    print(f"can't find the {name!r} module")

蟒蛇 3:

try:
    import mymodule
except ImportError as e:
    pass  # module doesn't exist, deal with it.

蟒蛇2:

try:
    import mymodule
except ImportError, e:
    pass  # module doesn't exist, deal with it.
于 2009-06-26T21:00:17.567 回答
64

更新的答案

一个更好的方法是:

import subprocess
import sys

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

结果:

print(installed_packages)

[
    "Django",
    "six",
    "requests",
]

检查是否requests安装:

if 'requests' in installed_packages:
    # Do something

为什么这样?有时您会遇到应用程序名称冲突。从应用程序命名空间导入并不能让您全面了解系统上安装的内容。

请注意,建议的解决方案有效:

  • 当使用 pip 从 PyPI 或任何其他替代源(如pip install http://some.site/package-name.zip或任何其他存档类型)安装时。
  • 使用手动安装时python setup.py install
  • 从系统存储库安装时,例如sudo apt install python-requests.

它可能不起作用的情况:

  • 在开发模式下安装时,例如python setup.py develop.
  • 在开发模式下安装时,例如pip install -e /path/to/package/source/.

旧答案

一个更好的方法是:

import pip
installed_packages = pip.get_installed_distributions()

对于 pip>=10.x 使用:

from pip._internal.utils.misc import get_installed_distributions

为什么这样?有时您会遇到应用程序名称冲突。从应用程序命名空间导入并不能让您全面了解系统上安装的内容。

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
于 2014-12-16T01:29:25.260 回答
64

As of Python 3.3, you can use the find_spec() method

import importlib.util

# For illustrative purposes.
package_name = 'pandas'

spec = importlib.util.find_spec(package_name)
if spec is None:
    print(package_name +" is not installed")
于 2017-01-23T21:23:04.567 回答
30

If you want to have the check from the terminal, you can run

pip3 show package_name

and if nothing is returned, the package is not installed.

If perhaps you want to automate this check, so that for example you can install it if missing, you can have the following in your bash script:

pip3 show package_name 1>/dev/null #pip for Python 2
if [ $? == 0 ]; then
   echo "Installed" #Replace with your actions
else
   echo "Not Installed" #Replace with your actions, 'pip3 install --upgrade package_name' ?
fi
于 2017-09-19T14:31:28.370 回答
6

As an extension of this answer:

For Python 2.*, pip show <package_name> will perform the same task.

For example pip show numpy will return the following or alike:

Name: numpy
Version: 1.11.1
Summary: NumPy: array processing for numbers, strings, records, and objects.
Home-page: http://www.numpy.org
Author: NumPy Developers
Author-email: numpy-discussion@scipy.org
License: BSD
Location: /home/***/anaconda2/lib/python2.7/site-packages
Requires: 
Required-by: smop, pandas, tables, spectrum, seaborn, patsy, odo, numpy-stl, numba, nfft, netCDF4, MDAnalysis, matplotlib, h5py, GridDataFormats, dynd, datashape, Bottleneck, blaze, astropy
于 2018-07-05T07:23:56.887 回答
5

Open your command prompt type

pip3 list
于 2020-03-10T14:59:07.197 回答
4

You can use the pkg_resources module from setuptools. For example:

import pkg_resources

package_name = 'cool_package'
try:
    cool_package_dist_info = pkg_resources.get_distribution(package_name)
except pkg_resources.DistributionNotFound:
    print('{} not installed'.format(package_name))
else:
    print(cool_package_dist_info)

Note that there is a difference between python module and a python package. A package can contain multiple modules and module's names might not match the package name.

于 2018-08-20T13:24:25.923 回答
4

In the Terminal type

pip show some_package_name

Example

pip show matplotlib
于 2020-02-22T20:27:01.263 回答
3
if pip list | grep -q \^'PACKAGENAME\s'
  # installed ...
else
  # not installed ...
fi
于 2020-07-21T16:54:22.313 回答
2

You can use this:

class myError(exception):
 pass # Or do some thing like this.
try:
 import mymodule
except ImportError as e:
 raise myError("error was occurred")
于 2019-12-01T17:42:07.650 回答
1

I'd like to add some thoughts/findings of mine to this topic. I'm writing a script that checks all requirements for a custom made program. There are many checks with python modules too.

There's a little issue with the

try:
   import ..
except:
   ..

solution. In my case one of the python modules called python-nmap, but you import it with import nmap and as you see the names mismatch. Therefore the test with the above solution returns a False result, and it also imports the module on hit, but maybe no need to use a lot of memory for a simple test/check.

I also found that

import pip
installed_packages = pip.get_installed_distributions()

installed_packages will have only the packages has been installed with pip. On my system pip freeze returns over 40 python modules, while installed_packages has only 1, the one I installed manually (python-nmap).

Another solution below that I know it may not relevant to the question, but I think it's a good practice to keep the test function separate from the one that performs the install it might be useful for some.

The solution that worked for me. It based on this answer How to check if a python module exists without importing it

from imp import find_module

def checkPythonmod(mod):
    try:
        op = find_module(mod)
        return True
    except ImportError:
        return False

NOTE: this solution can't find the module by the name python-nmap too, I have to use nmap instead (easy to live with) but in this case the module won't be loaded to the memory whatsoever.

于 2017-09-07T12:04:33.323 回答
1

Method 1

to search weather a package exists or not use pip3 list command

#**pip3 list** will display all the packages and **grep** command will search for a particular package
pip3 list | grep your_package_name_here

Method 2

You can use ImportError

try:
    import your_package_name
except ImportError as error:
    print(error,':( not found')

Method 3

!pip install your_package_name
import your_package_name
...
...
于 2022-01-02T05:27:39.713 回答
0

If you'd like your script to install missing packages and continue, you could do something like this (on example of 'krbV' module in 'python-krbV' package):

import pip
import sys

for m, pkg in [('krbV', 'python-krbV')]:
    try:
        setattr(sys.modules[__name__], m, __import__(m))
    except ImportError:
        pip.main(['install', pkg])
        setattr(sys.modules[__name__], m, __import__(m))
于 2018-02-02T13:05:21.857 回答
0

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
$
于 2018-09-20T01:02:00.903 回答
0

Hmmm ... the closest I saw to a convenient answer was using the command line to try the import. But I prefer to even avoid that.

How about 'pip freeze | grep pkgname'? I tried it and it works well. It also shows you the version it has and whether it is installed under version control (install) or editable (develop).

于 2019-10-07T21:04:45.667 回答
0

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

于 2020-05-29T20:08:50.760 回答
-1

去选项#2。如果ImportError被抛出,则该软件包未安装(或不在 中sys.path)。

于 2009-06-26T20:59:14.230 回答
-1

Is there any chance to use the snippets given below? When I run this code, it returns "module pandas is not installed"

a = "pandas"

try:
    import a
    print("module ",a," is installed")
except ModuleNotFoundError:
    print("module ",a," is not installed")

But when I run the code given below:

try:
    import pandas
    print("module is installed")
except ModuleNotFoundError:
    print("module is not installed")

It returns "module pandas is installed".

What is the difference between them?

于 2021-01-31T06:14:04.590 回答