虚拟环境下,pip 安装的包存储在哪里?

16 浏览
0 Comments

虚拟环境下,pip 安装的包存储在哪里?

情况:我创建了一个虚拟环境,并使用显式路径运行pip(而不是使用activate命令)。它会在全局dist-packages中安装软件包,还是安装在虚拟环境的site-packages中?

细节:Where does pip install its packages? 解释道,当使用虚拟环境时,pip会在/lib//site-packages中安装软件包。根据我的经验,当我激活虚拟环境时,这是正确的。我有一个现有的bash脚本,直接指定了pip可执行文件的路径,而不是激活虚拟环境。这样是否仍会将软件包安装在虚拟环境的site-packages中?还是安装在/local/lib//dist-packages中?

注意:我使用的是Ubuntu 16.04。

admin 更改状态以发布 2023年5月20日
0
0 Comments

当您使用显式路径到与venv关联的Python可执行文件时,例如.venv/bin/python3 -m pip install ...,那么pip将安装到虚拟环境的站点,例如.venv/lib/pythonX.Y/site-packages。在这种情况下,无论venv是否被激活都不重要。

但是,如果您使用将在$PATH中解析的命令,例如pip,而不是明确的命令path/to/python -m pip,那么事情可能会变得复杂。

  1. pip这样的裸命令所引用的可执行文件取决于$PATH。在which pip中查找正确的可执行文件(如果有人真的将其作为shell别名),请在which-a pip中查看其他挂起的内容,第一个文件可能会被遮蔽。请注意,某些shell会缓存命令到文件的映射,并且有时会搞砸其缓存失效(如果您看到奇怪的行为并且认为您的shell的缓存被搞砸,则尝试hash -r)。
  2. ./pip.venv/bin/pip这样的命令不会在$PATH中搜索。那是因为它有一个斜杠。
  3. 好了,所以你找到了你的文件pip,它是一个可执行的脚本。这个文件的第一行,称为shebang,告诉您与该pip脚本关联的解释器是哪一个。在head -1 .venv/bin/pip中查找。如果pip被安装到venv中,则这将始终匹配venv的Python,假设您没有手动编辑它,因为安装程序本身会将这个shebang写出来(有趣的事实:即使您直接将不同的shebang放在您的源代码中,安装程序也会重新写入!)。
  4. pip install将把文件放在关联解释器的sysconfig所说的位置。第1点告诉您"Pip"的确切含义,第2点向您展示了"关联解释器"的确切含义。sysconfig位置因平台而异。通过运行path/to/python -m sysconfig | grep "Paths:" --after 10并查找"purelib"路径来找出它们的位置。
  5. 不幸的是,Ubuntu用户还有一个额外的复杂性!这个发行版是Debian的衍生版,因此他们有一个修补过的distutils安装,由于Debian对Python包装的政策。TL;DR:在Ubuntu上,系统站点目录将被命名为dist-packages,而不是sysconfig报告的site-packages

激活venv并没有什么神奇之处,它只是设置了环境变量,例如$PATH。如果您了解1-3的工作原理,那么您就了解如何激活venv的工作原理。

现在您应该能够在没有猜测的情况下推理出答案:使用像.venv/bin/pip这样的路径与激活虚拟环境(更改$PATH,更改pip的含义,结果相同的.venv/bin/pip)没有区别。

附录:为什么人们在pip安装时遇到很多麻烦?

不良的卫生习惯。我认为他们通过某种方式(在启动脚本中附加,用户站点,sitecustomize.py,.bashrc中设置PYTHONPATH环境变量,安装一些垃圾包使其发生突变,按照某个垃圾指南安装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,该从pip模块导入的解析取决于sys.path。匹配第一项。当pip似乎随机损坏时,您应该始终问自己“此导入语句是否仍然找到安装程序创建脚本时编写的相同pip/__init__.py文件?”

如果没有,或者shebang看起来不正确,请只需将其删除并重新安装pip。

0
0 Comments

这非常取决于您的脚本正在使用哪个版本(不是语义版本意义上的版本,而是在创建venv时安装的pip的多个“版本”)以及其配置(包括可能的环境)。\n\n假设您的脚本有如下行:\n

/some/path/to/pip install 

\n\n假设pip已安装了至少一个软件包,您可以使用以下命令:\n

/some/path/to/pip show 

\n\n它会给您类似以下的输出:\n

$ 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:

\n\n倒数第二个位置的位置行应该有助于回答您的问题。

0