如何使用pip将Python软件包安装到不同的目录?

596
我知道显而易见的答案是使用virtualenv和virtualenvwrapper,但由于种种原因我不能/不想这样做。
那么我该如何修改命令?
pip install package_name

如何让 pip 将包安装到除默认的 site-packages 之外的其他地方?


2
现在是第二个问题:当您已经安装到自定义目录时,如何使 pip 不尝试从非自定义目录中删除旧版本。例如 - 系统范围内的一个目录,您没有写入权限。到目前为止,我只能使用 easy_install 完成此操作... - Tomasz Gandor
2
@TomaszGandor 我认为使用 --ignore-installed 选项应该可以防止pip尝试卸载已安装的软件包。 - Piotr Dobrogost
1
抱歉,我对pip不太熟悉,但您的问题是否与“如何让pi安装到不同版本的python”相同?我有Python 3.4和3.5,但我希望我的pip安装可以针对Python 3.5进行。 - Charlie Parker
可能不会出现问题,但我建议避免在同一个Docker镜像中同时安装Python3.4和3.5。我建议您自己提出问题 :) 其他人可能有更好的见解。 - Monika Sulik
显示剩余3条评论
20个回答

812

你需要的是--target开关:

pip install --target=d:\somewhere\other\than\the\default package_name

但是您仍然需要将d:\somewhere\other\than\the\default添加到PYTHONPATH中,才能从该位置实际使用它们。

-t,--target <dir>
将软件包安装到<dir>中。默认情况下,这不会替换<dir>中的现有文件/文件夹。
使用--upgrade将<dir>中的现有软件包替换为新版本。


如果目标开关不可用,请升级pip:

在Linux或OS X上:

pip install -U pip

对于Windows系统(这是解决问题的方法):

python -m pip install -U pip

8
请运行命令 pip install --upgrade pip 以升级pip。 - r3m0t
21
这是正确的答案,只是这个选项在被接受的答案之后添加了相当长一段时间。 - bukzor
8
“--install-option="--prefix=$PREFIX_PATH"”是@Ian Bicking提到的选项,与“--target=$PATH”选项有什么区别? - Hibou57
8
target 是pip的一个选项,install-option 中的所有内容都将传递给 setup.py install 命令。基本上 target 是一个自定义的site-packages位置。 - Janusz Skonieczny
14
使用 --target 可能会导致部分安装,因为它不会在指定的前缀中安装任何包括脚本或数据文件。似乎通过使用 --install-option 传递 --prefix 是唯一正确的方法来完全控制所使用的安装前缀。 - Kenneth Hoste
显示剩余20条评论

369

使用:

pip install --install-option="--prefix=$PREFIX_PATH" package_name

你可能还想使用 --ignore-installed 来强制重装所有依赖项,使用这个新的前缀。你可以使用 --install-option 多次添加任何你可以在 python setup.py install 中使用的选项(--prefix 可能是你想要的,但你也可以使用一堆其他选项)。


6
如果你这样做了,有没有办法让pip freeze命令看到备用目录? - Russ
7
pip freeze 会查找路径,因此如果你输入类似 PYTHONPATH=$PREFIX_PATH/lib/python2.6/site-packages pip freeze 的命令,它就能看到这些包。 - Ian Bicking
5
使用--prefix=$PREFIX_PATH似乎不能完全控制安装目录,因为系统会在其后添加特定的后缀(例如在Windows上为\Lib\site-packages)。有没有一种方法可以指定具体的目录? - Piotr Dobrogost
124
4年前的回答不错,但现在有“--target”选项了。 - Tritium21
2
PYTHONUSERBASE 环境变量与 pip 的 --user 选项结合使用,确保所有内容正确安装到指定的前缀中,但我的答案还没有像 --target 建议一样受到那么多关注。 - David Gardner
显示剩余12条评论

108

--target--install-options选项不同,我发现设置PYTHONUSERBASE环境变量可以很好地解决这个问题(来自于有关此事的bug的讨论):

PYTHONUSERBASE=/path/to/install/to pip install --user

(或在运行命令之前,在您的环境中设置PYTHONUSERBASE目录,使用export PYTHONUSERBASE=/path/to/install/to

这使用非常有用的--user选项,但告诉它在自定义前缀下创建binlibshare和其他您期望的目录,而不是$HOME/.local

然后,您可以像正常安装目录一样将其添加到PATHPYTHONPATH和其他变量中。

请注意,如果任何依赖此程序需要较新版本的软件包已安装在PYTHONUSERBASE目录中,请指定--upgrade--ignore-installed选项以覆盖系统提供的版本。

一个完整的示例

PYTHONUSERBASE=/opt/mysterypackage-1.0/python-deps pip install --user --upgrade numpy scipy

要将scipynumpy包的最新版本安装到一个目录中,然后可以将其包含在您的PYTHONPATH中,例如,使用bash和CentOS 6上的Python 2.6:

export PYTHONPATH=/opt/mysterypackage-1.0/python-deps/lib64/python2.6/site-packages:$PYTHONPATH
export PATH=/opt/mysterypackage-1.0/python-deps/bin:$PATH

使用 virtualenv 仍是更好、更整洁的解决方案!


4
这在使用运行在 Docker 容器上的 Travis CI 中起作用,而 "--install-option="--prefix=$PREFIX_PATH"" 的解决方案则不行。 - 32bits
1
新手问题,/bin 文件夹由 pip 创建,--user--PREFIX 命令也会创建它,但 --target 命令不会创建。这个文件夹有多重要? - Jonathan
1
此选项也与 --editable 和本地安装兼容。 - mdh
2
这个选项非常方便,可以为另一个非root用户安装软件包,而无需在用户之间切换(例如,在容器中可能会有问题)。 - mdh
1
我发现这个解决方案是自动解析目录下.pth文件的唯一方法。例如,当我将一个从site-packages复制并包含protobuf-3.1.0-py2.7-nspkg.pth和一个google目录的目录添加到PYTHONPATH中时,import google.protobuf会报错。但是PYTHONUSERBASE可以正常工作! - Tomas
显示剩余8条评论

53

14
“-t”是“--target”的简写。 - Jonathan
这是唯一对我有效的解决方案。(Windows 7) - Coliban

46

安装Python包通常只包含一些纯Python文件。如果包含数据、脚本或可执行文件,则这些文件将安装在不同的目录中,与纯Python文件分开。

假设您的包没有数据/脚本/可执行文件,并且您希望将Python文件放入/python/packages/package_name中(而不是像使用--prefix时将其放入几个子目录中),则可以使用以下一次性命令:

pip install --install-option="--install-purelib=/python/packages" package_name

如果您希望所有(或大多数)软件包安装到此位置,可以编辑您的~/.pip/pip.conf文件,并包含以下内容:

[install]
install-option=--install-purelib=/python/packages
那样,您就不会忘记一遍又一遍地指定它。除非您指定额外的安装选项(例如--prefix / --install-data / --install-scripts等),否则包中包含的任何可执行文件/数据/脚本仍将进入其默认位置。有关详细信息,请参见自定义安装选项。

2
配置文件是一个很大的优势。我个人在那里指定了 --prefix,因为我在共享服务器上有一个“本地”目录在主目录中,并且在我转移到 pip 之前,它被用作前缀。系统 $PATH$PYTHONPATH 已经配置好了。除了 install-option=--install-purelib=/blah,还有这个更新的 target=/blah 选项/开关。这也很好,但有时你只需要一个替代 --prefix 的东西,就像你会在 setup.pyeasy_install 中使用的那样。 - Tomasz Gandor
错误:在命令行中发现了 --install-option 中的位置更改选项:['--install-purelib']。这是不支持的,请使用 pip 级别选项,如 --user、--prefix、--root 和 --target。pip 版本为 22.0.4。 - user7610

32

使用python3.5和pip 9.0.3测试了以下选项:

pip install --target /myfolder [packages]

安装所有包及其依赖项到/myfolder下。不考虑依赖包已在Python的其他位置安装的情况。您将在/myfolder/[package_name]中找到包。如果您有多个Python版本,则此选项不会考虑该问题(包文件夹名称中不包含Python版本)。

pip install --prefix /myfolder [packages]

检查依赖项是否已安装。将程序包安装到/myfolder/lib/python3.5/site-packages/[packages]中。

pip install --root /myfolder [packages]

像--prefix一样检查依赖关系,但是安装位置将为/myfolder/usr/local/lib/python3.5/site-packages/[package_name]。

pip install --user [packages]

将程序包安装到$HOME中: /home/[USER]/.local/lib/python3.5/site-packages Python会自动从这个.local路径搜索,因此您无需将其添加到PYTHONPATH中。

=> 在大多数情况下,使用--user是最佳选择。 如果由于某种原因无法使用home文件夹,则使用--prefix。


1
在 Python 2.7.16 下运行,--target(或--prefix)会安装例如 Jinja2-2.10.1.dist-info/ 这样的版本,而使用 install --install-option="--prefix 会安装我实际想要的 Jinja2-2.10.1-py2.7.egg-info/ 版本。 - Greg Dougherty
并不总是通过环境变量起作用。 - x-yuri
您还可以在 $PYTHONUSERBASE 中设置目录,以安装 --user 安装的软件包。使用 --user 和设置 $PYTHONUSERBASE 与使用 --prefix 和设置 $PYTHONPATH 有什么区别吗? - Seppo Enarvi

25

1
@merv 这不同,因为它并不相同。不是吗? - Alex M.M.

21

似乎没有人提到-t选项,但这是最简单的方法:

pip install -t <direct directory> <package>

11
-t 选项是 --target 选项的简写,该选项已在另一个答案中进行了描述 (https://dev59.com/jnE85IYBdhLWcg3wKwKD#19404371) :) - MattiSG

16
pip install packageName -t pathOfDirectory

或者

pip install packageName --target pathOfDirectorty

这是另一个答案的副本(https://dev59.com/jnE85IYBdhLWcg3wKwKD#19404371)。 - Cristian Ciupitu

15

在 @Ian Bicking 的回答中再补充一点:

如果想要在远程服务器上安装某个Python包到自己的主目录(没有sudo用户权限),可以使用--user选项指定已安装的目录。

例如,

pip install --user python-memcached

该命令将把软件包安装到在你的PYTHONPATH中列出的目录之一。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接