在 Python 脚本中检查是否安装了包的好方法是什么?我知道解释器很容易,但我需要在脚本中完成。
我想我可以检查系统上是否有在安装过程中创建的目录,但我觉得有更好的方法。我正在尝试确保已安装 Skype4Py 软件包,如果没有,我将安装它。
我完成检查的想法
- 检查典型安装路径中的目录
- 尝试导入包,如果抛出异常,则安装包
在 Python 脚本中检查是否安装了包的好方法是什么?我知道解释器很容易,但我需要在脚本中完成。
我想我可以检查系统上是否有在安装过程中创建的目录,但我觉得有更好的方法。我正在尝试确保已安装 Skype4Py 软件包,如果没有,我将安装它。
我完成检查的想法
如果您的意思是 python 脚本,只需执行以下操作:
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")
try:
import mymodule
except ImportError as e:
pass # module doesn't exist, deal with it.
try:
import mymodule
except ImportError, e:
pass # module doesn't exist, deal with it.
一个更好的方法是:
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 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
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")
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
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
Open your command prompt type
pip3 list
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.
In the Terminal type
pip show some_package_name
Example
pip show matplotlib
if pip list | grep -q \^'PACKAGENAME\s'
# installed ...
else
# not installed ...
fi
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")
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.
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
You can use ImportError
try:
import your_package_name
except ImportError as error:
print(error,':( not found')
!pip install your_package_name
import your_package_name
...
...
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))
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
$
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).
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 as yaml
I am using python3.8
去选项#2。如果ImportError
被抛出,则该软件包未安装(或不在 中sys.path
)。
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?