几个 python 开发的虚拟环境

python 的标准库引入了 setuptools 之类的以后,很快 pip 的出世解决了开发人员获得依赖包的问题。感觉现在 C++ 这么长时间了还没能够获得一个类似的标准化,确实有点落伍了。同时这也引入了一种开发模式:通常系统带的 python 包都比较陈旧(系统维护人员决定的更新速度),而开发人员可能会有一些不同的要求,系统包与开发需求不匹配,因此一个比较常见的问题就是怎么替换掉系统包。

venv

这也是 python 标准库提供的一个基本的解决方案,通常我们只需要

$ python3 -m venv venv
$ source venv/bin/activate
$ pip3 install --upgrade pip

就能创建一个 venv 目录然后进入到该环境中,然后通过一组 pip 命令安装需要的包,通过 pip freeze 获得一个 requirements.txt,这样方便重新建立,比如在 docker 的部署说明文件 Dockerfile 里面可以用同样的 pip install -r requirements.txt 获得与开发环境一致的环境。

virtualenvwrapper

一个比较烦人的事情是通过 source venv/bin/activate 进入这个环境有点不方便,比如我们想设置一些环境变量之类的,就需要在在 activate 的前后做一些事情,也就是说我们需要一些 shell script 的整合,virtualenvwrapper 大概就将这一些常见的 shell magic 整理出来一套,我们通过

  • workon 进入某个环境
  • mkvirtualenv 创建一个环境

这里通常设置

  • export WORKON_HOME=$HOME/.virtualenvs 指定这些环境的位置
  • 然后需要将 virtualenvwrapper 提供的 completion script /usr/share/bash-completion/completions/virtualenvwrapper 连接到 /etc/bash_completion.d/ 目录里

conda / mamba

Conda 基本上将 virtual env 的想法发挥到极致,从某种程度上它甚至可以提供系统库,比如通常 pip 安装某些包会提示安装一些 -dev 的系统包,这是因为某些库安装需要编译连接到系统提供的某些库。conda 更进一步也提供了一些系统库、应用程序,更像是一个 dpkg + virtualenvwrapper 的合体。当然这个实现性能不一定很好,这导致后面有一些诸如 mamba 的实现,提升了一些性能,简化了 conda 的安装等等。

某些情况下特别是如果想选择不同的 python 版本,可能 conda 比起上面的两种加 pyenv 还是要方便很多的。

如何选择

官方的版本其实最容易获得,因此使用的代价偏低,但是一旦项目变得复杂可能不得不迁移到后面的选项。如果不介意在系统上安装 conda / mamba 的话可能这反而是一个一劳永逸的解决方案。

几个 python 开发的虚拟环境

一个有关“几个 python 开发的虚拟环境”的想法

  1. Coelacanthus 说:

    Conda 的问题是引入到虚拟环境的东西太多会导致很多原有环境程序坏掉,尤其是像 Qt 这样对插件 ABI 版本有严格要求的。Conda 支持默认激活虚拟环境更加剧了这个问题,在 Arch Linux CN 的群组里经常因为这个遇到应用无法正常运行的问题。

    1. zt 说:

      你说的默认激活虚拟环境是提供的那个 base environment 吗?如果在里面装了某些库和系统冲突就会导致问题?

      如果是这样,是不是不应该在 base 里面安装这些东西呢?

      毕竟 conda 不是 container,仅仅靠一些环境变量改变链接库的位置,肯定是有一定的局限性的。

    2. zt 说:

      明白,靠环境变量做这种定制化是存在这种风险的,一般还是在一个比较干净的 container 里面做部署会干扰少很多的。系统包跟虚拟环境并没有完全的隔离,一旦有个变量设置的不对或者混淆了,折腾错误 debug 都太花时间,不值得。

      感觉是比较熟悉 Linux 特别是 C/C++ 编译、链接关系的人会考虑的临时方案。但是一般不怎么熟悉、不想花时间调试问题的人,不建议这种混合搞法。

留下评论