关于 Python 的版本和开发环境管理

随着年纪的逐年攀升,有时候我们不得不把事情处理地有条理起来。这倒不全是因为人生阅历有了些许增长之后一个人开始有了格调,还在于那些需要我们着手去处理的事情往往变得越来越复杂,而与此同时我们的大脑却越来越不堪重负。

至少,当我们能在短时间内回想起一件重要的物件被置于何处,我们才能不至于耽误了工作行程。合理、科学地管理我们周身的事物乃至自身,是最有效的避免很多问题产生的关键。

越来越多地开发者转向 OSX 并不是没有道理,越来越多的开发社区开始倾向于构建强大的包(依赖)管理生态也不是空穴来风。就连当年「邋遢」的 PHP 都早已有了 Composer 这样名字意外文艺的包管理器,我们还有什么理由让自己的开发环境乱作一团?什么你说前端和 Node 的相关生态已经泛滥成灾到不知道该用哪个的地步了?手好痒。。

上学期某门必修课我们被要求基于 RoR 任意构建一个应用,于是乎在第一次接触 RubyRVM 之后,我惊奇地发现 Ruby 社区的大咖们个个都那么有格调,并一度认为他们每一个都是「洁癖」,直到被 Ruby 和 Rails 的版本问题坑到的同时又轻易被 RVM 拯救之后,我才迅速地自觉站队到了「洁癖」那一列。我虽然生于9月中旬,但我从没有像现在这么自豪过。

于是乎,现在但凡开始一件事,我都会彻底地调查清楚,在什么样的环境下,一件事还没开始做就似乎已经像是要成功了(不好意思这一定是病)。

 

我的选择


最近打算用用 Python ( JS 再往后放一下)。结果让人气馁的是,我发现当下竟然没有一个叫 PVM 的东西,没有这样的东西我还怎么写代码?(这真的是病)(以前写过,怪不得写成了X)好在其实类似的东西还是有的,只是都没有 RVM 来的那么正式和完善。我还没有病入膏肓,所以能用,看上去不是很差的也就这样接受了。

一番调查、比对之后,最终我选择的 Python 的版本、环境管理工具是 Pyenv-Virtualenv

在此我先简单地梳理下现在的大环境。首先大家都知道 RVM 基本用来做两件事, Ruby 的版本管理以及虚拟的开发环境管理。具体来讲,用 RVM 我们可以在指定目录指定特定的 Ruby 版本,并可以给相应的目录下的项目分割出独立于系统和其他任何项目的 Ruby 库和包( gems 之类)。这么做的好处在于项目与项目互相间的独立性,开发环境干净,不受污染。不同版本 Ruby 包括任何第三方的功能包的需求也可以灵活地实现。

那么现在我们来看 Python 。如果用 Google 去搜,我们很容易发现大部分人现在为了在 Python 下达到 Ruby RVM 的效果,都在使用两大工具,PyenvVirtualenv ,前者是纯粹的 Python 版本管理工具,而后者,则用于分割、管理 Python (开发)环境。简而言之,两者功能加起来才是 Ruby RVM 的效果。

另外,由于 Virtualenv 的指令一点也不简洁,有人另外给它封装了一层便于常人使用的接口,于是有了 VirtualenvWrapper 。但它并非一个独立的项目,需要 Virtualenv 安装妥当之后才能使用。

于是当下很多人选择的工具链就是 Pyenv + VirtualenvWrapper 的组合。但是看似美好的事情总有令人不舒服的地方。这样的组合是有不少问题的。首先它们根本就是两个相互独立的工具, Virtualenv 其实本身也可以对其划分出来的环境指定 Python 的版本,只是方式相较于 Pyenv 更显笨拙和低效(具体区别很容易找到,在此不表)。而如果配合 Pyenv 一起使用,效果虽然没什么问题,但是我们需要注意,由于两者各自做着自己的工作,导致原本应该一体的实现变得支离破碎,Pyenv 在自己的配置文件下管理着 Python 的版本而 Virtualenv 在自己的配置文件下管理着环境配置参数。在同一个项目之下, Python 版本和 Python 环境竟然是毫不相干地被管理支配着,不觉得可怕吗?

我想大家很显然都觉察到了这一点,于是有人站了出来,开发了 Pyenv-Virtualenv 这个一站式的解决方案。此人正是 Pyenv 的作者。而这个一站式的工具,其实又算是 Pyenv 的一个插件。虽然它确实是基于 Virtualenv 的也需要安装完备 Virtualenv ,但是却只使用一套配置文件同时管理 Python 版本及其开发环境,该配置文件默认存储在 ~/.pyenv 下。

 
Pyenv-Virtualenv 具体的使用方式简单罗列如下,

  1. # 原生 pyenv 工具就有的功能和指令
  2. # 首先是指定 Python 版本
  3. $ pyenv install -l
  4. ...
  5. 2.7.8
  6. 3.4.1
  7. .
  8. pypy-...
  9. .
  10. jython-..
  11. ..
  12. ..
  13. ...
  14. # 安装一个新的版本
  15. $ pyenv install 3.4.1
  16. ...
  17. ...
  18. ...
  19. ... successed!
  20. # 查看 pyenv 管理下的 Python 版本们
  21. $ pyenv versions
  22. * system (set by /Users/udonmai/.pyenv/version)
  23. 3.4.1
  24. # 指定当前目录下的 Python 版本是3.4.1 ( `local` 还可以由 `global` 和 `shell` 代替分别表示全局和当前终端 session 下)
  25. $ pyenv local 3.4.1
  26. # 查看当前 Python 版本
  27. $ python --version
  28. 3.4.1
  29. (如果切换到其他目录,再查看就是系统 Python 版本或者其他指定版本)
  1. # 现在开始是 Pyenv-Virtualenv 插件的功能和指令
  2. # 创建虚拟环境
  3. $ pyenv virtualenv 3.4.1 project_name
  4. # -> 这里注意了相对原生 pyenv 的命令,virtualenv 是必不可少的组成部分,之后接的是希望指定的该环境的 Python 版本号,再之后是该环境或者说项目的名称,这里我们就以 project_name 来命名我们创建的这个环境
  5. $ pyenv virtualenv project_name
  6. # -> 注意如果不指定 Python 的版本号,工具会将当前目录下已经指定的版本作为项目的 Python 版本号,如果没有以 `pyenv local ..` 之类的命令指定版本号,默认是系统的 Python
  7. # 这里有一点很有意思,有了 Pyenv-Virtualenv 插件后,创建的虚拟环境会同时出现在 Python 版本号列表和虚拟环境列表里
  8. # 首先是 Python 版本号列表展示
  9. $ pyenv versions
  10. * system (set by /Users/udonmai/.pyenv/version)
  11. 3.4.1
  12. project_name
  13. # 然后是虚拟环境列表展示
  14. $ pyenv virtualenvs
  15. project_name
  16. # 指定当前目录适用某虚拟环境
  17. $ pyenv local project_name(同样很有意思的地方,指定虚拟环境和上述的单独指定 Python 版本是同一个指令)
  18. # 取消设置
  19. $ pyenv local 3.4.1 --unset
  20. $ pyenv local project_name --unset
  21. # -> 依然是示范, global 和 shell 可作替换
  22. # 最后,如果希望删除某版本或者虚拟环境
  23. $ pyenv uninstall 3.4.1
  24. $ pyenv uninstall project_name

以上,该工具链最基本的功能就算是介绍完了,如果只用它们,日常的开发应该也已经没什么大问题了。

 

一点困惑


有一件曾让我心悸的事情我想还是有必要提一下,是关于上述工具作者的另外一个作品 Pyenv-VirtualenvWrapper 的。当我一开始寻找最合适的解决方案的时候,网上的资料给我的深刻印象是 VirtualenvWrapper 是为了方便我们而诞生的,那么这样一来 Pyenv-VirtualenvWrapper 势必会比 Pyenv-Virtualenv 更好用才是。但是这也是当时浪费我非常多时间的一个地方。

Pyenv-VirtualenvWrapper 的页面几乎没有什么文档资料,源码也出奇的少而简洁。即便看了源码,明白它根本没有实现什么东西,我还是不敢相信这个所谓的 Pyenv-VirtualenvWrapper 竟然只是一个为当前目录配置 VirtualenvWrapper 的「粗糙」工具,它并不是一个 Pyenv-Virtualenv 这样给 Pyenv 增加功能的插件,而只是帮你安装 VirtualenvWrapper 而已。

一开始我怎么也不相信,直到我看到一个 issue 页面,按作者的原话,

If you would like to manage virtual environments as same manner as pyenv, I would recommend you to use pyenv-virtualenv than pyenv-virtualenvwrapper.

最后我明白过来,Pyenv-VirtualenvVirtualenvWrapper 才是一个层级的工具,他们都是在 Virtualenv 之上又封装了一层,增加了额外的好用的指令和功能,而 Pyenv-VirtualenvWrapper ,其实基本没有存在的必要,通过分别安装 PyenvVirtualenvWrapper 就可以达到同样的效果。(说来好笑,Pyenv-VirtualenvWrapper 本来就只是一个类似安装脚本的东西)

 


最后,不得不说 Pyenv-Virtualenv 真的是一款相当有爱又实用的工具,那么在此就让我隆重推荐给各位同样有爱的朋友们

::...
免责声明:
当前网页内容, 由 大妈 ZoomQuiet 使用工具: ScrapBook :: Firefox Extension 人工从互联网中收集并分享;
内容版权归原作者所有;
本人对内容的有效性/合法性不承担任何强制性责任.
若有不妥, 欢迎评注提醒:

或是邮件反馈可也:
askdama[AT]googlegroups.com


订阅 substack 体验古早写作:


点击注册~> 获得 100$ 体验券: DigitalOcean Referral Badge

关注公众号, 持续获得相关各种嗯哼:
zoomquiet


自怼圈/年度番新

DU22.4
关于 ~ DebugUself with DAMA ;-)
粤ICP备18025058号-1
公安备案号: 44049002000656 ...::