使virtualenv继承特定的全局site-packages中的包

266

我正在寻找一种方法,可以创建一个仅包含我选择的基本Python安装库的虚拟环境。

更具体地说,我正在尝试在创建虚拟环境时将我的matplotlib导入到虚拟环境中。使用pip或easy_install无法有效安装它,因为缺少一些Fortran编译器库。我到目前为止所做的方式是手动从以下位置复制:

/usr/lib/python2.7/dist-packages/ to virtualenv_name/lib/python2.7/dist-packages/

然而,这会阻止手动导入的链接被yolk注册(yolk打印virtualenv中当前可用的所有库)。

那么,有没有办法进行选择性变体?

virtualenv --system-site-packages

@foobarbecue 我是原始的 OP。我目前没有设置测试环境,所以只要我能够测试答案,我就会立即接受答案。 - TheMeaningfulEngineer
2
看起来在过去的几个月里已经有12个人为您进行了测试... - foobarbecue
有关采纳答案的进展如何?看起来有一个答案是突出的... - Engineero
2
没有正确的答案。 OP 要求选择性地使用 --system-site-packages。 回答建议使用非选择性的 --system-site-packages,然后在本地安装一些软件包,这有不同的意义和影响。 - Piotr Jurkiewicz
2
2020已经很艰难了。请测试并接受答案,OP,我们不能再等了。 - Nicu Tofan
3
嘿,我是提问者 :) 距离我问这个问题已经有一段时间了,偶尔我会去看看答案是什么。最受欢迎的答案是一个非常好的解决方法,似乎被很多用户接受(根据票数)。然而,它会导致一个带有系统包的虚拟环境,这并不是解决方案。添加一步清理不需要的系统包的操作将是一个完整的修复方法。 - TheMeaningfulEngineer
4个回答

293

使用 virtualenv --system-site-packages 创建环境。然后,激活虚拟环境并在您想要安装虚拟环境中而不是系统 Python 中的东西时使用 pip install --ignore-installedpip install -I 。这样 pip 就会在本地安装您请求的内容,即使存在全局版本也是如此。您的 Python 解释器将首先查找虚拟环境的包目录,因此这些包应该遮盖全局的。


55
通过使用-I选项,即使系统范围的site-packages目录中已经存在包,也将始终重新安装它们。如果改用-U选项,则会将更新的软件包版本安装到您的虚拟环境中,但不会重新安装任何已在系统上以所需版本可用的软件包。 - Danilo Bargen
20
你知道是否有任何方法可以在先前创建的虚拟环境中“激活”--system-site-packages选项吗?我希望避免重新安装所有本地软件包所带来的麻烦! - Gabriel
17
是的,有。https://dev59.com/F3A75IYBdhLWcg3wS3FA - Mark
6
该问题要求使“某些”软件包可见,而不是除被隐藏的包外的“所有”软件包。白名单列出一组有限的软件包会比列出所有软件包更安全,因为它可以确保除了明确列出在白名单中的软件包之外,其余所有软件包必须存在于虚拟环境中。 - bluenote10
1
@foobarbecue 很遗憾,目前没有完美的解决方案。我找到的最佳解决方法是使用 这个答案,建议使用 --no-site-packages 并将整个包符号链接回 venv 到系统站点包。这似乎很有效,并允许精确控制在 venv 中可见的内容。 - bluenote10
显示剩余3条评论

20

您可以使用--system-site-packages,然后“覆盖安装”特定的虚拟环境内容。这样,您在虚拟环境中安装的所有内容都将来自该环境,否则将从您的系统中获取。


我不确定哪里不清楚,但我会尝试解释:如果你使用--system-site-packages选项创建一个虚拟环境,系统会首先在虚拟环境中查找包,如果没有找到,它会尝试在你的系统Python安装中查找。只有当它在这两个地方都找不到时,才会引发ImportError错误。 - schacki
7
这种方法的唯一问题是,你现在拥有了所有系统库,而你可能希望对安装什么有非常严格的控制。 - Dwayne
7
这究竟是如何可能的还不清楚!如果你在使用--system-site-packages创建的虚拟环境中使用pip install myprog,而myprog已经存在于系统中,它不会"覆盖安装"myprog。它只是会发现myprog已经存在,并显示"Requirement already satisfied." 那么...你的意思是什么呢? - foobarbecue
在虚拟环境中使用带有 --force-reinstall 参数的 pip 命令来“覆盖安装”已经存在于系统 site-packages 中的包。 - Gibrahh

1

我在使用Ubuntu 20.04上的python3.8和pip3方面有些晚了。

对我来说,摆脱烦人的.local安装的唯一方法是设置一个环境变量(bash):

export PYTHONNOUSERSITE="true"

这里并不需要是“真实”的,任何东西都可以。我不建议使用0. ;-)


-5

使用以下命令安装虚拟环境

virtualenv --system-site-packages

使用 pip install -U 安装matplotlib


4
这与问题所要求的相反。 - Dan Getz

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