检查是否安装了Python Package

时间:2009-06-26 20:54:38

标签: python package skype python-import

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

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

我完成检查的想法

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

17 个答案:

答案 0 :(得分:82)

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

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

答案 1 :(得分:42)

更新回答

更好的方法是:

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

为什么这样?有时你有app name collisions。从应用程序命名空间导入并不能全面了解系统上安装的内容。

旧答案

更好的方法是:

import pip
installed_packages = pip.get_installed_distributions()

对于pip> = 10.x使用:

from pip._internal.utils.misc import get_installed_distributions

为什么这样?有时你有app name collisions。从应用程序命名空间导入并不能全面了解系统上安装的内容。

结果,您获得了pkg_resources.Distribution个对象的列表。请参阅以下示例:

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)",
]

列出一份清单:

flat_installed_packages = [package.project_name for package in installed_packages]

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

检查是否安装了requests

if 'requests' in flat_installed_packages:
    # Do something

答案 2 :(得分:17)

如果您想从终端获得支票,可以运行

pip3 show package_name

如果没有返回任何内容,则不会安装软件包。

如果您想要自动执行此检查,那么例如,如果丢失则可以安装它,您可以在bash脚本中使用以下内容:

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

答案 3 :(得分:15)

从Python 3.3开始,您可以使用find_spec()方法

import importlib.util
import sys

# For illustrative purposes.
package_name = 'pandas'

spec = importlib.util.find_spec(package_name)
if spec is None:
    print(package_name +" is not installed")

答案 4 :(得分:4)

打开命令提示符类型

pip3 list

答案 5 :(得分:4)

作为this answer的扩展名:

对于Python 2。*,pip show <package_name>将执行相同的任务。

例如pip show numpy将返回以下内容:

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

答案 6 :(得分:2)

您可以使用setuptools中的pkg_resources模块。例如:

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)

请注意,python模块和python包之间有区别。一个程序包可以包含多个模块,并且模块名称可能与程序包名称不匹配。

答案 7 :(得分:1)

在终端类型中

pip show some_package_name

示例

pip show matplotlib

答案 8 :(得分:1)

我想在本主题中添加一些我的想法/发现。 我正在编写一个脚本来检查自定义程序的所有要求。 python模块也有很多检查。

存在一些问题
try:
   import ..
except:
   ..

溶液。 在我的情况下,其中一个python模块名为python-nmap,但是您使用import nmap导入它,并且您看到名称不匹配。因此,使用上述解决方案的测试返回False结果,并且它还会在命中时导入模块,但可能不需要使用大量内存进行简单的测试/检查。

我也发现了

import pip
installed_packages = pip.get_installed_distributions()

installed_packages 只有已安装pip 的软件包。 在我的系统上pip freeze返回40个python模块,而installed_packages只有1,我手动安装的那个(python-nmap)。

下面的另一个解决方案,我知道可能与问题无关,但我认为保持测试功能与分开是一种很好的做法执行安装它可能对某些人有用。

对我有用的解决方案。它基于这个答案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

注意:此解决方案也无法通过名称python-nmap找到模块,我必须使用nmap代替(易于使用),但在这种情况下,模块赢了&#39 ;无论如何都要加载到内存中。

答案 9 :(得分:0)

如果您希望自己的脚本安装缺失的软件包并继续,可以执行以下操作(例如&#39; krbV&#39;模块中的&#39; python-krbV&#39;软件包):

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))

答案 10 :(得分:0)

一种快速的方法是使用 python 命令行工具。 只需键入import <your module name> 如果缺少模块,则会看到错误。

$ 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
$

答案 11 :(得分:0)

嗯...我看到的最方便的答案是使用命令行尝试导入。但我什至宁愿避免这种情况。

“冻结点”如何? grep pkgname'?我试过了,效果很好。它还显示了它的版本以及是在版本控制下(安装)还是可编辑(开发)安装。

答案 12 :(得分:0)

class myError(exception):  通过#或做某事 尝试:  导入mymodule 除了ImportError作为e:  引发myError(“发生错误”)

答案 13 :(得分:0)

我想评论@ ice.nicer的回复,但我不能,所以... 我的观察结果是,带有破折号的软件包使用下划线保存,而不仅仅是@dwich注释所指出的点

例如,您执行pip3 install sphinx-rtd-theme,但是:

  • importlib.util.find_spec(sphinx_rtd_theme)返回一个对象
  • importlib.util.find_spec(sphinx-rtd-theme)返回None
  • importlib.util.find_spec(sphinx.rtd.theme)引发ModuleNotFoundError

此外,某些名称已完全更改。 例如,您进行了pip3 install pyyaml,但是它只是另存为yaml

我正在使用python3.8

答案 14 :(得分:0)

if pip3 list | grep -sE '^some_command\s+[0-9]' >/dev/null
  # installed ...
else
  # not installed ...
fi

答案 15 :(得分:-1)

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

答案 16 :(得分:-1)

有没有机会使用下面给出的片段?当我运行此代码时,它返回“未安装模块熊猫”

a = "pandas"

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

但是当我运行下面给出的代码时:

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

它返回“安装了模块熊猫”。

它们之间有什么区别?