如何让 virtualenv 在 Ubuntu 上使用 dist-packages?
Posted
技术标签:
【中文标题】如何让 virtualenv 在 Ubuntu 上使用 dist-packages?【英文标题】:How to get virtualenv to use dist-packages on Ubuntu? 【发布时间】:2013-10-13 04:58:44 【问题描述】:我知道 virtualenv,如果在创建新的虚拟环境时没有传递 --no-site-packages
参数,会将 /usr/local/lib/python2.7/site-packages
(对于 Python 2.7)中的包与新创建的虚拟环境链接。在 Ubuntu 12.04 LTS 上,我有三个可以安装 Python 2.7 包的位置(使用默认的 Ubuntu 提供的 Python 2.7 安装):
/usr/lib/python2.7/dist-packages
:这是我的 ipython、scipy、numpy、matplotlib 的全局安装——如果无法通过 scipy stack 获得它们,我会发现单独安装这些软件包(及其所有依赖项)既困难又费时。李>
/usr/local/lib/python2.7/site-packages
:这是空的,我认为除非我从源代码安装包,否则它将在 Ubuntu 上保持这种状态。
/usr/local/lib/python2.7/dist-packages
:这里有非常重要的天文学本地包,尤其是与 PyRAF、STScI 等相关的包,单独安装非常困难和耗时。
请注意,我的系统上不存在诸如 /usr/lib/python2.7/site-packages
之类的全局目录。另请注意,我的 ipython、scipy 等全局安装让我可以即时使用这些包,而无需每次都获取/激活虚拟环境。
当然,我现在想使用 virtualenv 在我的用户主目录中创建一个虚拟环境,我将为我未来的项目获取/激活它。但是,我希望这个虚拟环境在创建时能够链接/复制上面列表中位置 (1) 和 (3) 中的所有包。造成这种情况的主要原因是我不想通过pip install
进程(如果可能的话)为这个(可能还有其他)虚拟重新安装 ipython、scipy、astro 包等环境。
这是我的问题:
-
我有没有办法向 virtualenv 指定我希望它为将来创建的虚拟环境链接/复制这两个
dist-packages
目录中的包?
当我最终在两个 dist-packages
目录中更新我的 scipy、ipython 等全局安装时,这是否也会更新/更改我的虚拟环境使用的包(以及它最初在 virtualenv 创建期间获得的包)?
如果我曾经在 Ubuntu 上从源代码安装包,它会进入 /usr/local/lib/python2.7/dist-packages
还是 /usr/local/lib/python2.7/site-packages
?
提前感谢您的帮助!
【问题讨论】:
【参考方案1】:这可能是PYTHONPATH
的合法使用——virtualenv
不涉及的环境变量,它使用与 bash 中的环境变量 PATH
相同的语法 PYTHONPATH=/usr/lib/python2.7/dist-packages:/usr/local/lib/python2.7/dist-packages
在 .bashrc 或类似文件中.如果你走这条路,
您根本不必告诉您的虚拟环境,它不会尝试更改它。
不需要重新链接,并且
如果你将它们安装在你的虚拟环境之外,它仍然会去任何它应该去的地方(pip install
总是使用 /usr/local/lib/python2.7/dist-packages/ 对于我的 Ubuntu)。如果您从虚拟环境中安装它们(当它被激活时),那么它当然会被放入虚拟环境中。
【讨论】:
这很好用,谢谢!另一种方法是创建一个.pth 文件,其中每一行都是要添加到默认sys.path 的路径,并将该文件放在虚拟环境的站点包目录中,例如@ 中的dist-packages.pth 987654327@。我现在选择了后一种方法,因为它更清楚地说明了为什么这个特定的虚拟环境可以访问全局 dist-packages 目录,而不是 .bashrc 中的“全局”PYTHONPATH
环境变量。
啊,那也不错。有时我在虚拟环境中将一些东西添加到激活脚本中,您可以在那里设置和取消设置 PYTHONPATH,但由于 .pth 文件可以工作,这可能会更好。不过,它是处理其他类似事情的好地方。
这很好用。在按照这个答案规定的方式设置 PYTHONPATH 之前,我无法从 virtualenv pip install numpy。
使用 .pth 文件与配置管理配合得很好,因为在设置过程中将预制文件复制到适当的位置很简单。
我有 Ubuntu 14.04,对我来说,/usr/lib/python2.7 归 root 所有。我正在尝试运行使用 virtualenv(或任何必要的方法)来使用 Jenkins 运行 Python unittest 测试。我的 jenkins 系统用户无权访问这些目录。我宁愿不将我的 jenkins 用户添加到根组。我在这里做错了什么?【参考方案2】:
PYTHONPATH
为我工作。
vim ~/.bashrc
在下面添加这一行:
export PYTHONPATH=$PYTHONPATH:/usr/lib/python2.7/dist-packages:/usr/local/lib/python2.7/dist-packages
source ~/.bashrc
【讨论】:
如果 /usr/lib/python2.7/dist-packages 由 root 拥有并且您使用的是非 root 系统帐户怎么办?【参考方案3】:您想要在这里实现的本质上是将特定文件夹 (dist-packages
) 添加到 Python 搜索路径。为此,您有多种选择:
-
使用路径配置 (
.pth
) 文件,条目将附加到系统路径。
修改PYTHONPATH
(其中的条目转到系统路径的开头)。
直接从您的 Python 脚本修改 sys.path
,即将所需的文件夹附加到它。
我认为对于这种特殊情况(启用全局dist-packages
文件夹),第三个选项更好,因为使用第一个选项,您必须为您将要工作的每个virtualenv 创建.pth
文件在(使用一些外部 shell 脚本?)。分发包裹时很容易忘记它。第二个选项需要运行时设置(添加一个 envvar),这也是很容易错过的。
只有第三个选项在配置或运行时不需要任何先决条件,并且可以毫无问题地分发(当然,在相同类型的系统上)。
你可以这样使用函数:
def enable_global_distpackages():
import sys
sys.path.append('/usr/lib/python2.7/dist-packages')
sys.path.append('/usr/local/lib/python2.7/dist-packages')
然后在你的包的__init__.py
文件中:
enable_global_distpackages()
【讨论】:
【参考方案4】:我只是在了解 virtualenv,但似乎有比目前提到的更简单的方法。
因为virtualenv 1.7 --no-site-packages 一直是默认行为。
因此,使用--system-site-packages
标志到 virtualenv 是在你的路径中获取 dist 包所需要的全部 - 如果你使用 Ubuntu 提供的经过调整的 virtualenv。 (This answer 和 this one 给出了一些有用的历史记录)。我已经对此进行了测试,它确实有效。
$ virtualenv --system-site-packages .
我同意 Thomas 的观点 - 我看不到 virtualenv 中需要执行任何操作来查看 dist-packages 中更新的效果。
已经用python setup.py install
测试过,它确实(再次如 Thomas 所说)仍然进入 dist-packages。你可以通过构建自己的 python 来改变这一点,但这有点极端。
【讨论】:
【参考方案5】:在site-packages
目录下,创建文件dist.pth
在文件 dist.path 中,输入以下内容:
../dist-packages
现在停用并激活您的 virtualenv。你应该准备好了。
【讨论】:
以上是关于如何让 virtualenv 在 Ubuntu 上使用 dist-packages?的主要内容,如果未能解决你的问题,请参考以下文章
如何在Ubuntu 20.04 GCP实例上安装virtualenv?
使用virtualenv在ubuntu上搭建python 3开发环境