虚拟环境可以优先使用用户包而非系统包吗?

6 投票
1 回答
1265 浏览
提问于 2025-04-18 04:37

我在 Emacs 中使用 Jedi 来实现 Python 的自动补全功能,但这个工具并不是我代码的必要部分,所以我不想把它放进我的 requirements.txt 文件里。(其他开发者可能不使用 Jedi 编辑器插件,而且在我部署到 Heroku 时,这个插件也不是必须的。)

不过,Jedi 必须在我的虚拟环境中可用才能正常工作,也就是说,如果我不能

import jedi

它就无法运作。

有没有什么好的方法可以全局安装 Jedi,这样它在我所有的虚拟环境中都能使用呢?

觉得 我想要的是:

  1. pip--user 选项 把 Jedi 安装到 ~/.local/lib/python2.7/site-packages/,然后
  2. 创建我的虚拟环境时,使用类似于 --system-site-packages 选项 的方法,但针对的是 用户包 而不是系统包。

我现在的解决办法是每个虚拟环境里都执行 pip install jedi。然后当我添加新依赖时,我会执行 pip install foo,接着用 pip freeze > requirements.txt 生成依赖列表,然后在提交之前手动把 jedi 和其他几个东西从文件中删掉。显然,这样做既耗时又容易出错。

有没有人有更好的解决方案呢?

1 个回答

4

当你使用 virtuenvactivate 命令时,它会改变一些环境变量,比如 PATHPYTHONHOMEPS1 等,这些变量会指向你想要的 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

撰写回答