检查Python包是否安装
在 Python 脚本中检查软件包是否已安装的好方法是什么? 我知道这对于解释器来说很容易,但我需要在脚本中完成。
我想我可以检查系统上是否有安装过程中创建的目录,但我觉得有更好的方法。 我正在尝试确保 Skype4Py 软件包已安装,如果没有,我将安装它。
我完成检查
- 典型安装路径中目录的
- 想法尝试导入包,如果抛出异常,则安装包
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 guess I could check if there's a directory on the system that's created during the installation, but I feel like there's a better way. I'm trying to make sure the Skype4Py package is installed, and if not I'll install it.
My ideas for accomplishing the check
- check for a directory in the typical install path
- try to import the package and if an exception is throw, then install package
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(21)
在终端类型
示例中
In the Terminal type
Example
作为这个答案的扩展:
对于Python 2.*,
pip show
将执行相同的任务。例如
pip show numpy
将返回以下或类似内容: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:您可以使用 setuptools 中的 pkg_resources 模块。 例如:
请注意,python 模块和 python 包之间存在差异。 一个包可以包含多个模块,并且模块的名称可能与包名称不匹配。
You can use the pkg_resources module from setuptools. For example:
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.
方法1
使用pip3 list命令搜索包是否存在
方法2
可以使用ImportError
方法3
Method 1
to search weather a package exists or not use pip3 list command
Method 2
You can use ImportError
Method 3
你可以使用这个:
You can use this:
我想在这个主题中添加一些我的想法/发现。
我正在编写一个脚本来检查定制程序的所有要求。 python 模块也有很多检查。
解决方案有点问题
。
就我而言,其中一个名为 python-nmap 的 python 模块,但是您使用 import nmap 导入它,并且您看到名称不匹配。 因此,使用上述解决方案的测试返回 False 结果,并且它还会在命中时导入模块,但可能不需要使用大量内存来进行简单的测试/检查。
我还发现
installed_packages
将仅包含已使用 pip 安装的软件包。在我的系统上,
pip freeze
返回超过40
个 python 模块,而installed_packages
只有1
,即我手动安装的模块(python-nmap)。下面的另一种解决方案,我知道它可能与问题无关,但我认为将测试功能与执行安装的功能分开是一种很好的做法对某些人有用。
对我有用的解决方案。 它基于这个答案如何检查 python 模块是否存在而不导入它
注意:此解决方案无法找到该模块也通过名称
python-nmap
,我必须使用nmap
(易于使用),但在这种情况下,模块不会被加载到内存中。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
solution.
In my case one of the python modules called
python-nmap
, but you import it withimport 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
installed_packages
will have only the packages has been installed with pip.On my system
pip freeze
returns over40
python modules, whileinstalled_packages
has only1
, 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
NOTE: this solution can't find the module by the name
python-nmap
too, I have to usenmap
instead (easy to live with) but in this case the module won't be loaded to the memory whatsoever.我想对 @ice.nicer 回复发表评论,但我不能,所以......
我的观察是,带有破折号的包用下划线保存,而不仅仅是像 @dwich 评论指出的那样用点保存。
例如,您执行
pip3 install sphinx-rtd-theme
,但是:importlib. util.find_spec(sphinx_rtd_theme)
返回一个对象importlib.util.find_spec(sphinx-rtd-theme)
返回 Noneimportlib.util.find_spec(sphinx.rtd.theme)< /code> 引发 ModuleNotFoundError
此外,一些名称完全改变了。
例如,您执行
pip3 install pyyaml
但它只是保存为yaml
我正在使用 python3.8
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 Objectimportlib.util.find_spec(sphinx-rtd-theme)
returns Noneimportlib.util.find_spec(sphinx.rtd.theme)
raises ModuleNotFoundErrorMoreover, some names are totally changed.
For example, you do
pip3 install pyyaml
but it is saved simply asyaml
I am using python3.8
如果您希望脚本安装缺少的软件包并继续,您可以执行以下操作(以“python-krbV”软件包中的“krbV”模块为例):
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):
一种快速的方法是使用python命令行工具。
只需输入
import <您的模块名称>
如果模块丢失,您会看到错误。
A quick way is to use python command line tool.
Simply type
import <your module name>
You see an error if module is missing.
嗯...我看到的最接近方便的答案是使用命令行来尝试导入。 但我什至更愿意避免这种情况。
'pip freeze | 怎么样? grep pkgname'? 我尝试了一下,效果很好。 它还向您显示它的版本以及它是在版本控制(安装)还是可编辑(开发)下安装的。
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).
我一直使用 pylibcheck 来检查库是否已安装,只需通过执行以下操作即可下载它pip install pylibcheck 可能是这样的,
它还支持元组和列表,因此您可以检查多个包,如果它们已安装,
您也可以使用它安装库(如果您想这样做),建议您查看官方 pypi
I've always used pylibcheck to check if a lib is installed or not, simply download it by doing
pip install pylibcheck
and the could could be like thisit also supports tuples and lists so you can check multiple packages and if they are installed or not
you can also install libs with it if you want to do that, recommend you check the official pypi
投票最高的解决方案使用
importlib.util.find_spec
和sys.modules
等技术并捕获导入异常,适用于大多数包,但在某些边缘情况下会失败(例如 < code>beautifulsoup 包),其中导入中使用的包名称与安装文件配置中使用的包名称有些不同(在本例中为bs4
)。 对于这些边缘情况,除非您传递导入中使用的包名称而不是requirements.txt
或pip
安装中使用的包名称,否则此解决方案不起作用。对于我的用例,我需要编写一个包检查器来根据
requirements.txt
检查已安装的包,因此该解决方案不起作用。 我最终使用的是subprocess.check
显式调用 pip 模块来检查包安装:它比其他方法慢一点,但更可靠并且可以处理边缘情况。
The top voted solution which uses techniques like
importlib.util.find_spec
andsys.modules
and catching import exceptions works for most packages but fails in some edge cases (such as thebeautifulsoup
package) where the package name used in imports is somewhat different (bs4
in this case) than the one used in setup file configuration. For these edge cases, this solution doesn't work unless you pass the package name used in imports instead of the one used inrequirements.txt
orpip
installations.For my use case, I needed to write a package checker that checks installed packages based on
requirements.txt
, so this solution didn't work. What I ended up using wassubprocess.check
to call the pip module explicitly to check for the package installation:It's a bit slower than the other methods but more reliable and handles the edge cases.
虽然并不完美,但以下解决方案通常比
pip show ...
快得多,并且也适用于多个包While not perfect, the following solution is usually much quicker than
pip show ...
and also works for multiple packages选择选项#2。 如果抛出
ImportError
,则说明该包未安装(或不在sys.path
中)。Go option #2. If
ImportError
is thrown, then the package is not installed (or not insys.path
).有机会使用下面给出的片段吗? 当我运行此代码时,它返回“模块 pandas 未安装”
但是当我运行下面给出的代码时:
它返回“模块 pandas 已安装”。
它们之间有什么区别?
Is there any chance to use the snippets given below? When I run this code, it returns "module pandas is not installed"
But when I run the code given below:
It returns "module pandas is installed".
What is the difference between them?
如果您指的是 python 脚本,只需执行以下操作:
Python 3.3+ use sys.modules and find_spec:
Python 3:
Python 2:
If you mean a python script, just do something like this:
Python 3.3+ use sys.modules and find_spec:
Python 3:
Python 2:
从 Python 3.3 开始,您可以使用 find_spec() 方法
As of Python 3.3, you can use the find_spec() method
更新的答案
更好的方法是:
结果:
检查是否安装了请求:
为什么这样? 有时您会遇到应用程序名称冲突的情况。 从应用程序命名空间导入并不能让您全面了解系统上安装的内容。
请注意,建议的解决方案有效:
pip install http://some.site/package-name.zip
或任何其他存档类型) 。python setup.py install
手动安装时。它可能无法工作的情况:
python setup.pydevelop
。pip install -e /path/to/package/source/
。旧答案
更好的方法是:
对于 pip>=10.x 使用:
为什么这样? 有时您会遇到应用程序名称冲突的情况。 从应用程序命名空间导入并不能让您全面了解系统上安装的内容。
结果,您将获得
pkg_resources.Distribution
对象的列表。 请参阅以下示例:列出它:
检查
requests
是否已安装:Updated answer
A better way of doing this is:
The result:
Check if
requests
is installed: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:
pip install http://some.site/package-name.zip
or any other archive type).python setup.py install
.sudo apt install python-requests
.Cases when it might not work:
python setup.py develop
.pip install -e /path/to/package/source/
.Old answer
A better way of doing this is:
For pip>=10.x use:
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:Make a list of it:
Check if
requests
is installed:如果您想从终端进行检查,可以运行
,如果没有返回任何内容,则说明该软件包尚未安装。
如果您想自动执行此检查,以便在丢失时安装它,则可以在 bash 脚本中包含以下内容:
If you want to have the check from the terminal, you can run
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:
打开命令提示符类型
Open your command prompt type