什么是检查,如果包装是一个Python脚本中同时安装一个好办法吗? 我知道这是从解释容易,但我需要一个脚本中做到这一点。
我想我可以检查是否有是一个的安装过程中创建的系统上的目录,但我觉得有一个更好的办法。 我想,以确保安装了Skype4Py包,如果没有,我会安装它。
我对完成检查的想法
- 检查一个目录中的典型安装路径
- 尝试导入包,如果有异常抛出,然后安装包
什么是检查,如果包装是一个Python脚本中同时安装一个好办法吗? 我知道这是从解释容易,但我需要一个脚本中做到这一点。
我想我可以检查是否有是一个的安装过程中创建的系统上的目录,但我觉得有一个更好的办法。 我想,以确保安装了Skype4Py包,如果没有,我会安装它。
我对完成检查的想法
如果你说的是python脚本,只是做这样的事情:
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
为什么这样? 有时候,你有应用程序名称冲突。 从应用程序的命名空间导入不给你一个什么样的系统上安装的全貌。
这样做的更好的方法是:
import pip
installed_packages = pip.get_installed_distributions()
用于PIP> = 10.x的用途:
from pip._internal.utils.misc import get_installed_distributions
为什么这样? 有时候,你有应用程序名称冲突。 从应用程序的命名空间导入不给你一个什么样的系统上安装的全貌。
其结果是,你得到的名单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
如果你想有来自终端的检查,你可以运行
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
对于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")
作为一个扩展这样的回答 :
对于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
您可以使用从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包之间的差异。 包可以包含多个模块和模块的名称可能不匹配的包名。
我想我的一些想法/结果添加到这个话题。 我正在写一个脚本来检查的定制计划的所有要求。 有使用Python模块太多的检查。
有一个小问题与
try:
import ..
except:
..
解。 在我的情况被称为Python模块的一个python-nmap
,但你导入import nmap
,正如你看到的名称不匹配。 因此,与上述解决方案的测试返回错误的结果,而且还导入模块上的打击,但也许没有必要使用大量的内存为一个简单的测试/检查。
我还发现,
import pip
installed_packages = pip.get_installed_distributions()
installed_packages
将只有包已安装了点子 。 在我的系统pip freeze
返回超过40
python模块,而installed_packages
仅具有1
,我手动安装了一个(蟒-NMAP)。
低于另一种解决方案,我知道它可能不相关的问题 ,但我认为这是一个很好的做法,以保持测试功能与执行安装,可能是一些有用的一种独立的 。
为我工作的解决方案。 它基于这个答案如何检查是否存在Python模块而不导入它
from imp import find_module
def checkPythonmod(mod):
try:
op = find_module(mod)
return True
except ImportError:
return False
注意:此方法无法找到该名模块python-nmap
过,我必须使用nmap
代替(易住在一起),但在这种情况下,模块不会被加载到任何记忆。
如果你想你的脚本安装缺少的软件包并继续,你可以做这样的事情(例如上的“krbV”在“中的python-krbV”封装模块):
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))
一个快速的方法是使用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
$
进入选项#2。 如果ImportError
被抛出,然后包未安装(或不在sys.path
)。