在代码中安装python模块


309

我需要直接在脚本中从PyPi安装软件包。也许有一些模块或distutilsdistributepip等)功能使我可以执行类似的操作,pypi.install('requests')并且请求将被安装到我的virtualenv中。


4
为什么不在自己程序包的setup.py中将相关模块定义为依赖项?
Andreas Jung 2012年

5
您知道...实际上应该完成的方式...但是您始终可以使用os.system(“ pip install blah”),但您可能需要sudo访问...最好使其成为安装程序的依赖项。 py
Joran Beasley 2012年

2
您是否会考虑在此处更改已接受的答案?导入pip绝不是一个好主意-仅凭其所有内容都_internal从版本10开始...
Antti Haapala,

2
@chuwy stackoverflow.com/a/50255019/918959 <=这个。pip._internal不是设计为可导入的,而是在另一个程序中导入时可以做绝对随机的事情。
安蒂·哈帕拉

3
@AnttiHaapala好的,我更改了它。我个人不喜欢这两种解决方案,但是这些天我与Python距离很远,所以我相信您的意见。
chuwy

Answers:


251

从脚本安装软件包的官方推荐方法是通过子进程调用pip的命令行界面。pip不支持此处提出的大多数其他答案。此外,自pip v10起,所有代码都已pip._internal精确定位,以使用户清楚不允许以编程方式使用pip。

使用sys.executable,以确保您将调用相同pip与当前运行相关联。

import subprocess
import sys

def install(package):
    subprocess.check_call([sys.executable, "-m", "pip", "install", package])

这样做的一个问题是,对于Windows上的新手用户,python和pip并不总是位于其PATH上,因此可以双击一个.py文件会非常方便,而可以使用“ pip install xxx”注释相当棘手。
jdpipe

CalledProcessError:命令'[' C:\\ ProgramData \\ \\ Anaconda3 pythonw.exe ' '-M', '点子', '装', 'googleapiclient']'返回非零退出状态1
parvij

381

您还可以使用类似:

import pip

def install(package):
    if hasattr(pip, 'main'):
        pip.main(['install', package])
    else:
        pip._internal.main(['install', package])

# Example
if __name__ == '__main__':
    install('argh')

3
@nbro会将选项传递给pip.main()您,就像在命令行上一样(但每个选项都作为列表中的单独条目而不是单个字符串)。并指定所需的软件包版本,请与命令行上的操作相同。例如:pip.main(['install', 'pip==7.1.0'])
Kaos

3
另请参阅stackoverflow.com/questions/6457794/…,其中显示了如何处理安装失败的情况。
P. Myer Nore

24
from pip._internal import main as pipmain那么你可以使用pipmain()就像过时的pip.main()stackoverflow.com/questions/43398961/...
Bjorks头号粉丝

17
现在它已经过时了。
摩尔斯

6
由于某种原因不推荐使用,不再推荐了。参见pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program
NBK

71

如果要用于pip安装所需的软件包并在安装后将其导入,则可以使用以下代码:

def install_and_import(package):
    import importlib
    try:
        importlib.import_module(package)
    except ImportError:
        import pip
        pip.main(['install', package])
    finally:
        globals()[package] = importlib.import_module(package)


install_and_import('transliterate')

如果您以用户身份安装软件包,则可能会遇到不能仅导入软件包的问题。请参阅如何刷新sys.path?有关其他信息。


4
任何想法如何在Python 3上做到这一点?imp.reload(site)得到我RuntimeError: dictionary changed size during iteration
kgadek

我在哪里安装了软件包,在这样做之后,我做不到pip uninstall <package_name>。我仍然可以使用来卸载它,pip.main但只想知道它将软件包安装在哪里?
Ishan Khare

很好奇 如果我这样做会正常工作pip install requests[security]吗?我不确定它是否正确定义了全局变量。
Fallenreaper

4

22

这应该工作:

import subprocess

def install(name):
    subprocess.call(['pip', 'install', name])

1
是的,绝对可以。但是我认为这是一种更优雅的方式;)我会稍等一下,也许有。
胖乎乎的2012年

1
@Downvoter:我的答案到底出了什么问题?该答案具有所有OP所需要的。它甚至不使用外壳。
2012年

13
这取决于正确的pip版本是否在路径上。如果用户正在运行其他python安装,则pip将安装到第一个安装中,而不是当前安装中。上面的导入方法将安装在正确的位置。无论如何,我都投票反对这次否决。
GaryBishop 2014年

6
根据脚本的运行方式,您不会调用正确的点。
纳蒂姆

5
打电话[sys.executable, '-m', 'pip', 'install', name]确保在这里得到“正确的”点子。
wim

12

我在@Aaron的答案中添加了一些异常处理。

import subprocess
import sys

try:
    import pandas as pd
except ImportError:
    subprocess.check_call([sys.executable, "-m", "pip", "install", 'pandas'])
finally:
    import pandas as pd

1
子流程和pip的良好实现,比这里的大多数解决方案都要好
Shantanu Shady

3
您没有检查的retunr值,subprocess.call因此代码可能会失败。
安蒂·哈帕拉

5

您可以使用“ install_requires”选项在自己程序包的setup.py中定义从属模块。

如果您的软件包需要生成一些控制台脚本,则可以使用“ console_scripts”入口点来生成包装脚本,该脚本将被放置在“ bin”文件夹(例如您的virtualenv环境)中。


1
这是正确的答案,也是管理Python项目依赖项的唯一明智的方法。它将与virtualenv,Fabric,buildout一起使用。@xiaomao描述的方法,即使准确回答了OP的要求,也纯粹是疯狂的。
卢卡斯·格拉夫

7
尽管这是适当的建议,但并不能回答所提出的问题
Corey Goldberg

2
尽管打包是一个主题,但还有许多其他用例,例如,用python编写的部署脚本。
hoefling '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.