虚拟环境可以优先使用用户包而非系统包吗?
我在 Emacs 中使用 Jedi 来实现 Python 的自动补全功能,但这个工具并不是我代码的必要部分,所以我不想把它放进我的 requirements.txt
文件里。(其他开发者可能不使用 Jedi 编辑器插件,而且在我部署到 Heroku 时,这个插件也不是必须的。)
不过,Jedi 必须在我的虚拟环境中可用才能正常工作,也就是说,如果我不能
import jedi
它就无法运作。
有没有什么好的方法可以全局安装 Jedi,这样它在我所有的虚拟环境中都能使用呢?
我 觉得 我想要的是:
- 用
pip
的--user
选项 把 Jedi 安装到~/.local/lib/python2.7/site-packages/
,然后 - 创建我的虚拟环境时,使用类似于
--system-site-packages
选项 的方法,但针对的是 用户包 而不是系统包。
我现在的解决办法是每个虚拟环境里都执行 pip install jedi
。然后当我添加新依赖时,我会执行 pip install foo
,接着用 pip freeze > requirements.txt
生成依赖列表,然后在提交之前手动把 jedi
和其他几个东西从文件中删掉。显然,这样做既耗时又容易出错。
有没有人有更好的解决方案呢?
1 个回答
4
当你使用 virtuenv
的 activate
命令时,它会改变一些环境变量,比如 PATH
、PYTHONHOME
和 PS1
等,这些变量会指向你想要的 Python 程序、库等等。你可以修改这个脚本,让 PYTHONPATH
指向你的用户安装包,也就是 ~/.local/lib/python2.7/site-packages
,还有可能指向你的系统安装包。这样设置后,pip 会先在虚拟环境中查找库,如果找不到,再去用户或系统的安装包中查找。需要注意的是,通常情况下,激活脚本并不会改变 PYTHONPATH
。
也就是说,你可以在你的 virtual_env/bin/activate
文件中添加以下几行代码。
# in activate script
# in deactivate function
if [ -n "$_OLD_VIRTUAL_PYTHONPATH" ] ; then
PYTHONPATH="$_OLD_VIRTUAL_PYTHONPATH"
export PYTHONPATH
unset _OLD_VIRTUAL_PYTHONPATH
fi
# in activate section
if [ -n "$PYTHONPATH" ] ; then
_OLD_VIRTUAL_PYTHONPATH="$PYTHONPATH"
PYTHONPATH=$HOME/.local/lib/python2.7/site-packages:/usr/lib/python2.7/site-packages
fi