Handling Python enviroments

python2 将在 2020 年结束支持,许多项目已经开始迁移或者计划迁移到 python3 上面。IPython 已经在新版本中取消 python2 支持;Django 2.0 取消 python2 支持,numpy 即将结束 python2 支持。

大家终于开始接受 python3 了,不过在这个时期内,处理 python 版本问题变的愈加痛苦。最近 macOS 上流行的包管理工具 Homebrew 做了非常激进的一步,它们把 python 链接到 python3 了,这甚至违反了 PEP394 而招致一部分人不满。当我执行 brew upgrade 之后,一些 python 写的工具没法用了。

所以不得重新整理这些 python 版本的管理工具、策略,很多曾经写下的配置现在已经不知道时什么作用了。趁这个机会重新梳理一遍。

注意,我使用的操作系统是 macOS,shell 用的是 fish,下面这些设置可能并不适合其他组合。一些工具的使用方式这里不一一列出,如果你感兴趣,可以点击链接查看详细的使用方法。

命令行工具

一些命令行工具是用 python 写的,比如说 fabric、ansible、pipenv。这些工具一般来说应该是安装在系统的 python 上面,pip 会自动链接命令到比如说 /usr/local/bin 下面,这样你就可以直接在终端里面输入 fab 而不是 /path/to/python -m fabric

不过我不想把系统的 python 搞的乱七八糟的,而且这非常不方便管理,比如说你要更新某个工具的时候,或者你要卸载某个工具的时候,因为不同的工具可能只能运行在某个版本的 python 上,当你要更新、卸载它们的时候,首先你需要找到它们安装在哪个解释器上。

所以,我使用 pipsi 来管理这些命令行工具。

相比 Homebrew 上的 python,操作系统自带的 python 更新比较没有那么频繁,所以稍微修改了一点安装方法,能够减少因为更新 python 导致的问题。

1
2
3
curl -sSL https://bootstrap.pypa.io/get-pip.py | sudo -H /usr/bin/python
sudo /usr/bin/python -m pip install virtualenv
curl https://raw.githubusercontent.com/mitsuhiko/pipsi/master/get-pipsi.py | sudo /usr/bin/python

这样安装 python 的命令行工具:

1
pipsi install fabric

如果需要指定解释器版本:

1
pipsi install --python python3 jupyterlab

更新、删除某个工具变的非常方便

1
2
3
pipsi upgrade fabric
# or
pipsi uninstall fabric

项目执行环境

virtualenv

最常用就是 virtualenv 了,这其实也是一个命令行工具,不过他过于基础, 甚至一些环境管理工具也依赖它,所以比较适合安装在系统级别,在上一节,更具体的,应该把它和这些管理工具安装在同一个 python 解释器上。virtualenv 已经安装在系统的 python 上面了,所以不需要再安装一次,直接用就可以了。

我一般会把运行环境放在项目的目录下面,这样,在文本编辑器上,可以在项目目录上看到运行环境的目录。一些文本编辑器会索引项目的文件,比如说 Sublime Text ,你可以使用 cmmand + P 非常快速的定位到你想查看的文件。

virtualenvwrapper (virtualfish)

这个工具对我来说,最主要的目是,当我要试用某个第三方包的时候,我希望可以快速的创建一个执行环境,尝试一下,完事之后直接删除这个环境,确保操作系统的整洁。

virtualenvwrapper 包含了这样一个命令 mktmpenv 它会自动创建一个临时文件夹,设置好 python 的环境,就像 virtualenv 已将,你可以直接指定 virtualenv 的参数,比如说 --python 设置 python 的版本。额外的,他还会设置一些钩子,当你退出这个环境后 (deactivate),这个临时文件夹会自动删除。

不过 virtualenvwrapper 好像不支持 fish, 所以才有另外一个工具,virtualfish ,它做的事情基本上和 virtualenvwrapper 一样,而且还有一个插件,提供了 virtualenvwrapper 一样的命令。而且对于创建临时环境这件事上,做的比 virtualenvwrapper 还要好,不只是在 deactivate 后自动删除,你关闭终端的时候它也会自动删除。

因为 virtualfish 并没有设置命令行的 entrypoint 所以没办法用 pipsi 安装:

1
2
sudo /usr/bin/python -m pip install virtualfish
echo 'eval (/usr/bin/python -m virtualfish compat_aliases)` >> ~/.config/fish/config.fish

以上