如何自动安装缺少的python模块?
我想能写:如何自动安装缺少的python模块?
try:
import foo
except ImportError:
install_the_module("foo")
什么是处理这种情况的建议/惯用方法是什么?
我见过很多脚本只是打印一个错误或警告,通知用户有关缺少的模块和(有时)提供有关如何安装的说明。但是,如果我知道该模块在PyPI上可用,那么我肯定可以进一步启动安装过程。没有?
安装问题不是源代码的主题!
您可以使用install_requires
配置在包 的setup.py
内正确定义您的相关性。
这就是要走的路......由于ImportError
安装的东西有点怪异和可怕。不要这样做。
尽管setup.py本身需要所需的模块,但这并没有帮助。是否有setup()提供的某种钩子可以允许它通过setup_requires安装setup-time依赖关系,然后在setup()的同一个调用中使用该新安装的依赖关系中定义的命令类,而不会添加过多的样板文件为每个使用该依赖关系的包设置setup.py? – hosford42 2016-05-31 16:00:14
我添加了[一个新问题](http://*.com/questions/37551598/providing-a-custom-command-class-to-setup-py-in-a-separately-installed-package)来解决我的问题具体的用例。 – hosford42 2016-05-31 16:59:50
try:
import foo
except ImportError:
sys.exit("""You need foo!
install it from http://pypi.python.org/pypi/foo
or run pip install foo.""")
请勿触摸用户的安装。
下面是我放在一起的解决方案,我称之为pyInstall.py
。它实际上检查模块是否安装,而不是依靠ImportError
(在我看来,看起来更干净,用if
而不是try
/except
来处理)。
我已经在版本2.6和2.7下使用它...如果我不想处理print
作为函数,它可能会在旧版本中工作......我认为它可以在版本3.0+但我从来没有尝试过。
而且,正如我在getPip
功能评论请注意,我不认为特定的功能将在OS X下
from __future__ import print_function
from subprocess import call
def installPip(log=print):
"""
Pip is the standard package manager for Python. Starting with Python 3.4
it's included in the default installation, but older versions may need to
download and install it. This code should pretty cleanly do just that.
"""
log("Installing pip, the standard Python Package Manager, first")
from os import remove
from urllib import urlretrieve
urlretrieve("https://bootstrap.pypa.io/get-pip.py", "get-pip.py")
call(["python", "get-pip.py"])
# Clean up now...
remove("get-pip.py")
def getPip(log=print):
"""
Pip is the standard package manager for Python.
This returns the path to the pip executable, installing it if necessary.
"""
from os.path import isfile, join
from sys import prefix
# Generate the path to where pip is or will be installed... this has been
# tested and works on Windows, but will likely need tweaking for other OS's.
# On OS X, I seem to have pip at /usr/local/bin/pip?
pipPath = join(prefix, 'Scripts', 'pip.exe')
# Check if pip is installed, and install it if it isn't.
if not isfile(pipPath):
installPip(log)
if not isfile(pipPath):
raise("Failed to find or install pip!")
return pipPath
def installIfNeeded(moduleName, nameOnPip=None, notes="", log=print):
""" Installs a Python library using pip, if it isn't already installed. """
from pkgutil import iter_modules
# Check if the module is installed
if moduleName not in [tuple_[1] for tuple_ in iter_modules()]:
log("Installing " + moduleName + notes + " Library for Python")
call([getPip(log), "install", nameOnPip if nameOnPip else moduleName])
下面是一些用法示例工作:
from datetime import datetime
from pyInstall import installIfNeeded
# I like to have my messages timestamped so I can get an idea of how long they take.
def log(message):
print(datetime.now().strftime("%a %b %d %H:%M:%S") + " - " + str(message))
# The name fabric doesn't really convey to the end user why the module is needed,
# so I include a very quick note that it's used for SSH.
installIfNeeded("fabric", notes = " (ssh)", log = log)
# SoftLayer is actually named softlayer on pip.
installIfNeeded("SoftLayer", "softlayer", log = log)
编辑:让pipPath的更多的跨平台的方式是:
from subprocess import Popen, PIPE
finder = Popen(['where' if isWindows() else 'which', 'pip'], stdout = PIPE, stderr = PIPE)
pipPath = finder.communicate()[0].strip()
这使得假设pip
将被安装在系统路径上。它在非Windows平台上往往非常可靠,但在Windows上最好在原始答案中使用代码。
冒着反对票,我想建议一个快速入侵。请注意,我完全接受了答案,应该从外部管理依赖关系。
但是,你绝对需要破解的东西,就像自包含的情况下,可以尝试一些象下面这样:
import os
try:
import requests
except ImportError:
print "Trying to Install required module: requests\n"
os.system('python -m pip install requests')
# -- above lines try to install requests module if not present
# -- if all went well, import required module again (for global access)
import requests
os.system已弃用...使用子流程模块 – 2017-01-20 16:26:55
它在理论上很好,但它在现实中的一个痛苦的屁股。只需让用户自己安装软件包,或者在将软件包创建为依赖项时提供它们。 – 2011-05-25 08:34:27
@JakobBowyer - 你的第一句话总结了人们得到报酬所做的大部分事情 - 如果某件事是一个好主意并且不难做到,那么它就已经完成了,任何人都不需要支付别人去通过PITA。我在工作中付出了努力编写一个脚本,该脚本能够自动部署服务器,并且可以在没有任何用户交互的情况下运行,因此我需要自动处理Python模块尚未安装的情况。现在,世界可以从我的收入中获益 - 我将它记录在下面:http://*.com/a/25643988/901641 – ArtOfWarfare 2014-09-03 12:17:01
5 upvotes不会使你的Python风格符合PEP8 – 2017-01-20 16:37:40