如何检查Python中是否安装了一个模块,并在需要时进行安装?

在终端中,当我启动Python后,我如何知道Python中有哪些模块? 假设我需要学习NumPy和SciPy这两个模块。
  • 如果它们未安装,我该如何安装?
  • 如果已经安装了,我该如何知道?
15个回答

如何判断系统中是否安装了Python模块:您可以在终端中进行一个非常简单的测试,
$ python -c "import math"
$ echo $?
0                                # math module exists in system

$ python -c "import numpy"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named numpy
$ echo $?
1                                # numpy module does not exist in system

如果它尚未安装,我该如何安装它

您可以通过从存储库下载相应的软件包来安装特定模块,例如您可以像这样安装 scipy

sudo apt-get install python-scipy ## for Python2
sudo apt-get install python3-scipy ## for Python3
< p > < strong > 或者 您还可以按照Zack Titan在下面的评论中建议的方式使用python-pip安装Python模块。要安装numpy,您可以执行以下操作:
pip install numpy
警告:强烈建议仅使用官方的Ubuntu软件库安装Python模块,而不要使用超级用户(即root或使用sudo)的pip方法。在某些情况下,这可能会破坏系统Python导致您的系统无法使用。

如何使用pip在本地虚拟环境中安装软件包。


就像你的回答中所说,数学模块是存在的,对于numby来说,没有出现任何回溯错误,并且对于echo $?命令的输出结果为0。这是否意味着numpy也存在于我的系统中? - sigdelsanjog
2是的,在您的系统中有它。 - sourav c.
如果您没有numpy模块,您将如何导入它?当我们编写代码时,我们通过“from numpy import *”调用导入语句,这会安装该模块吗?如果不是,我们将如何安装新模块? - sigdelsanjog
如果你在调用一个模块时遇到错误,这意味着该模块没有安装在你的系统中。不,它不会自动安装模块。 - sourav c.
1如何安装模块是一个独立的问题。不同的模块需要不同的软件包。例如,要安装vpython,您需要执行以下命令:sudo apt-get install python-visual libgtkglextmm-x11-1.2-dev - sourav c.
你也可以使用pip来安装模块。但首先,需要先安装pip。输入sudo apt-get install python-pip来安装pip,然后要安装模块,只需输入pip install numpy即可。 - thuyein
@ZackTitan 当前版本的Python已经预装了pip,因此您可以直接使用python -m pip install命令进行安装,无需额外安装pip作为外部程序。 - Bakuriu
@Bakuriu哦,我不知道。当我安装它时,我必须通过easy_install和distribute来安装pip。我想这是在Windows上完成的。但是Linux要简单得多。谢谢你的信息。 - thuyein
@ZackTitan:pip也已经包含在Windows上的Python中(自Python 2.7.9和Python 3.4起)。运行python -m ensurepip,确保pip已安装在那里。 - jfs
1不要使用sudo pip,因为它可能会破坏系统的Python。请使用apt-get命令安装适用于系统Python的软件包。你可以使用pip --user选项或者virtualenv来安装适用于自己的Python软件包。 - jfs
@J.F.Sebastian 我同意你的观点,并加上了警告。 - sourav c.
@souravc:重点是避免使用sudo,而不是pip。我经常使用pip在本地虚拟环境中安装各种包。 - jfs
@J.F.Sebastian 我只提到了这一点。请阅读最后一行,即“如果以超级用户身份运行”,也就是以 root 或使用 sudo 的方式。 - sourav c.
值得一提的是,您可以使用pip命令和pip list命令查找已安装在特定环境中的内容。 - Steve Barnes
在Windows中使用 python -c "import math" 然后 echo %ERRORLEVEL% - Hans Ginzel

如果我们不想在需要的时候无意中导入一个模块(这会在try语句中发生),我们可以利用sys.modules来测试已安装之前已导入的模块。
在Python shell中输入:
>>> import sys

然后测试已安装的模块:
>>> 'numpy' in sys.modules
True
>>> 'scipy' in sys.modules
False

请注意,只有在此测试之前导入的模块才会返回True,所有其他模块(即使已安装)都会返回False
另一个在Python控制台中尝试import语句的替代方法是调用内置的help()函数。这不会为未安装的模块提供文档,例如。
>>> help('scipy')
no Python documentation found for 'scipy'

非常长的帮助文档输出可以通过按下 Q 键来中断。
现在,为了安装缺失的模块,建议使用Ubuntu软件包管理器(而不是Python pip方式),因为我们需要root访问权限,并且还要防止损坏我们严重依赖Python的系统。对于所讨论的模块,例如:
sudo apt-get install python-scipy ## for Python2
sudo apt-get install python3-scipy ## for Python3

安装后,我们可以通过导入一次将它们添加到sys.modules字典中。

1我认为这是最符合Python风格的答案。 - Grijesh Chauhan
4这个的第一部分是错误的:sys.modules 只包含已经被导入的模块,所以它不是一个可靠的方法来测试一个模块是否已经安装。最可靠的测试方法是使用 try/except 并捕获 ImportError,正如其他人已经建议的那样。 - ekhumoro
@ekhumoro - 谢谢,我会编辑我的回答,使其更加清晰明了。 - Takkat
5似乎还不够清楚。鉴于问题是询问如何判断一个模块是否“已安装”(而不是“已导入”),sys.modules 是完全无关的,我认为提及它可能会误导。但也许这只是我的看法。 - David Z
2sys.modules在这里没有任何帮助。 - cat
导入一个模块用于检查有什么问题吗?导入起来真的很耗费资源吗? - K.-Michael Aye

另一种方法是使用pkgutil模块。适用于Python 2和3版本。
python -c 'import pkgutil; print(1 if pkgutil.find_loader("module") else 0)'

你需要用你的模块名称替换module,例如:
$ python -c 'import pkgutil; print(1 if pkgutil.find_loader("math") else 0)'
1

2我看到你撤销了我的一些更改;在Python 2中,print()也可以正常工作;它被视为带有括号的组语法,并且没有任何副作用。只有当你想要添加多个项目(如print('a', 'b'))时,它将被视为一个tuple,在这种情况下,你确实需要from __future__ import print_function,但在这种情况下不适用,你只需通过添加括号来编写向前兼容的代码(我在Python 2和3中测试了我的更改)。 - Martin Tournoij
@地毯烟民:谢谢你的指出。我回滚到旧版本了。 - cuonglm
这是一个很棒的答案。我添加了一个派生答案,它返回一个退出/状态码(用于Shell脚本流程控制),并将模块名称作为命令行参数。https://askubuntu.com/a/891384/146273 - Bruno Bronosky
那个起作用了! - 只需将其更改为exit,以便在shell环境中使用:python -c 'import pkgutil; exit(0 if pkgutil.find_loader("math") else 2)' - A T

我知道原始问题是关于在开始使用Python后寻找解决方案,但在Python之外,我使用pip。在Ubuntu上,如果尚未安装,请运行sudo apt-get install python-pip

然后,要查看可用的第三方模块,只需运行:

pip freeze

甚至连
pip list

并且两者都会显示您安装的所有模块及其版本。
如果您要查找的模块未安装,大多数情况下您可以使用pip轻松安装它。
pip install <module-name>
If you're not sure of whether a module exists or what its PyPI name is, use `pip search`:
pip search <keyword>
看起来 pip search 不再起作用了。(请参见下面 @AJM 的评论)。我倾向于直接使用 Pypi 的搜索功能

2另外,pip show <module-name> 命令可以显示一个包是否已安装,例如 pip show numpy - Herpes Free Engineer
pip search 不再可用:PyPI的XMLRPC API已被禁用。有关此决定背后的原因,请参阅https://www.theregister.com/2021/05/25/pypi_search_error/ - 但该文章是在禁用API仅为临时的情况下编写的。在一月份,已发出电子邮件公告将其永久禁用。 - AJM
1感谢 @AJM。已更新。 - OozeMeister

你可以把代码放在try和except块中。
$ python3 -c "\
try:
    import cow  
    print('\nModule was installed')
except ImportError:
    print('\nThere was no such module installed')"

There was no such module installed

$ python3 -c "\
try:
    import regex
    print('\nModule was installed')
except ImportError:
    print('\nThere was no such module installed')"

Module was installed

为了完整起见,提供另一个答案:
您可以滥用 `-m` 选项。来自Python的man页:
   -m module-name
          Searches sys.path for the named module and runs the  correspond‐
          ing .py file as a script.

这将给我们带来:
$ python2 -m numpy
/sbin/python2: No module named numpy.__main__; 'numpy' is a package and cannot be directly executed

$ python2 -m math
/sbin/python2: No code object available for math

但对于不存在的模块,它将给我们返回:
$ python2 -m doesnt_exist
/sbin/python2: No module named doesnt_exist

我们可以使用grep来匹配这个。
$ python2 -m doesnt_exist |& grep -q 'No module named' && echo 'Nope' || echo 'Yup'
Nope

$ python2 -m math |& grep -q 'No module named' && echo 'Nope' || echo 'Yup'
Yup

这有点取巧,不是 -m 的本意;但如果你想要一个快速测试的话,这是最省力的方法 :-)

5grep -q 使重定向到 null 变得不必要。 - muru
4@muru 哎呀!这些年来,我打了很多无用的重定向到/dev/null :-/ - Martin Tournoij

我用Python写了一个例子:
import pip
import sys
from bigml.api import BigML


if not 'bigml' in sys.modules.keys():
    pip.main(['install', 'bigml'])

Shell单行检查(用于虚拟机部署)

我发现为了使我的基础设施部署具有幂等性,我需要能够在一个单行命令中从shell检查软件包。我在 @cuonglm 的答案基础上进行了修改。我不得不反转 10,因为我需要生成一个退出状态而不是打印一个字符串。

python -c "import sys, pkgutil; sys.exit(0 if pkgutil.find_loader(sys.argv[1]) else 1)" pymongo

你可以用你的包的单引号名称替换sys.argv[1],但是对于我的配置脚本,我喜欢将其放在最后以增加可读性。
python -c "import sys, pkgutil; sys.exit(0 if pkgutil.find_loader('pymongo') else 1)"

我意识到 chef, puppet, 和 ansible 都有管理 Python 包的插件,但你可能会遇到和我一样的情况,使用了过时的版本并且不想使用已弃用的插件。



从Ubuntu Shell,默认情况下是bash,就像这样简单。
pip list | grep <package-name-Case-Matters>

例子
pip list | grep pywinrm

pip list | grep numpy

如果你对这个案例有疑问的话(尽管我认为所有的包名都是小写的):
pip list | grep [Nn]um[Pp]y  # it works with numpy, Numpy, numPy, and NumPy