pip 在哪里安装带有虚拟环境的软件包?
Posted
技术标签:
【中文标题】pip 在哪里安装带有虚拟环境的软件包?【英文标题】:Where does pip install packages with a virtual environment? 【发布时间】:2020-02-27 23:48:14 【问题描述】:情况:我创建了一个虚拟环境并使用显式路径来运行pip
(没有采购activate
)。它是在全局dist-packages
中安装软件包还是将它们安装在虚拟环境的site-packages
中。
详情:
正如Where does pip install its packages? 解释的那样,当与虚拟环境一起使用时,pip 会在<virtualenv_name>/lib/<python_ver>/site-packages
中安装包。根据我的经验,当我激活 virtualenv 时这是真的。我有一个现有的 bash 脚本,它直接指向 pip
可执行文件,而无需激活 virtualenv。这是否仍然在 virtualenv 的站点包中安装包?还是将它们安装在/local/lib/<python-version>/dist-packages
中?
注意:我使用的是 Ubuntu 16.04
【问题讨论】:
在 *ix 下,检查您正在调用的脚本的第一行(即$VIRTUAL_ENV/bin/pip
)以了解它引用的是哪个 Python - 以及哪个包安装目标。
Virtualenv "activation" 只是修改了PATH
变量,所以正确的可执行文件被预先设置(它实际上做的不止这些,但在这里不相关)。因此source env/bin/activate && pip install
与直接调用env/bin/pip install
相同。
@blubberdiblub 你说的“*ix”是什么意思?
@Code-Apprentice Linux、Unix、MacOS
【参考方案1】:
这在很大程度上取决于您的脚本使用的 pip 的 哪个 版本(不是语义版本意义上的,而是在创建 venv 时安装的 pip 的多个“版本”) ,以及它的配置(可能包括您的环境)。
假设你的脚本有这样一行
/some/path/to/pip install <some package>
并且假设 pip 已经安装了至少一个包,你可以使用
/some/path/to/pip show <that package>
它会为您提供如下所示的输出:
$ pip show numpy
Name: numpy
Version: 1.14.5
Summary: NumPy: array processing for numbers, strings, records, and objects.
Home-page: http://www.numpy.org
Author: Travis E. Oliphant et al.
Author-email: None
License: BSD
Location: /usr/lib/python3/dist-packages
Requires:
倒数第二个位置行应该有助于回答您的问题。
【讨论】:
【参考方案2】:pip
等裸命令在文件系统上引用的可执行文件取决于 $PATH。在which pip
中查找正确的那个(type pip
如果有人真的很邪恶并为它做了一个 shell 别名)。查看which -a pip
以查看其他人在附近徘徊,第一个可能正在阴影中。请注意,某些 shell 会缓存命令到文件的映射,有时会破坏它们的缓存失效(如果您看到奇怪的行为并且您认为您的 shell 有一个混乱的缓存,请尝试hash -r
)。
诸如./pip
或.venv/bin/pip
之类的命令将不会搜索$PATH。那是因为它有一个斜线。
好的,你已经找到了你的文件pip
,它是一个可执行脚本。该文件的第一行,称为 shebang,告诉您哪个解释器与该 pip 脚本相关联。查看head -1 .venv/bin/pip
。如果将 pip 安装到 venv 中,那么这将始终与 venv 的 Python 匹配,假设您没有手动编辑它,因为安装程序本身会写出这个 shebang(有趣的事实:即使您直接在源代码中放置了一个不同的,安装程序重写了它!)。
pip install
将把文件放在相关解释器的 sysconfig 所说的位置。第 1 点准确地告诉您“pip”的含义,第 2 点准确地向您展示了“相关解释器”的含义。 sysconfig 位置取决于平台。通过运行path/to/python -m sysconfig | grep "Paths:" --after 10
找出位置并查找“purelib”路径。
“激活”一个 venv 并没有什么神奇之处,它只是设置了诸如 $PATH 之类的环境变量。如果您了解 1-3 的工作原理,那么您就会了解激活 venv 的工作原理。
所以现在你应该能够在不猜测的情况下推断出答案:使用类似 .venv/bin/pip
的路径与激活 venv (这会改变 $PATH,这会改变 pip
的含义,导致相同的 .venv/bin/pip
)使得没有区别。
附录: 为什么人们在安装 pip 时遇到这么多麻烦?
Bad hygiene. 我认为他们以某种方式搞砸了sys.path
(在启动脚本、用户站点、sitecustomize.py 中附加它,在 .bashrc 中设置 PYTHONPATH
env var,安装一些糟糕的包改变了它,遵循一些糟糕的指南,有一个sudo pip install
...可能性是无穷无尽的!)
查看pip
“脚本”,它只是由 setuptools 编写的控制台入口点。此脚本是在安装时从模板创建的。您实际上不会在 pip 的源代码中的任何地方找到此文件,因为 它不存在。
#!/path/to/.venv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from pip._internal.main import main # <--- look at this import statement!
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())
可执行脚本所做的第一件事是尝试从pip
模块 导入其私有API,而from pip
模块导入的解决位置取决于sys.path
。第一场比赛获胜。当 pip 出现随机损坏时,您应该始终问自己“此导入语句是否仍然找到安装程序在创建脚本时写出的相同 pip/__init__.py
文件?”
如果不是,或者 shebang 看起来不对,只需将其删除并重新安装 pip。
【讨论】:
以上是关于pip 在哪里安装带有虚拟环境的软件包?的主要内容,如果未能解决你的问题,请参考以下文章