学会搭建环境

注意,本文介绍的 brew、pip 作为包管理器,使用的过程中,需要处于联网的状态,以防万一,如果下载某个 package 的过程中失败,请确保可以真正地连入国际互联网。

如何让 Python 2 与 Python 3 共存

上一篇内容,我们已经了解 Python 环境相关的知识,由于 Python 现在推荐的版本是 3,而 MacOS 内置的 Python 版本是 2。为了系统的稳定,我们不能直接将 MacOS 系统所依赖的 Python 2 直接升级为 Python 3,因此,我们需要全新安装一个 Python 3,并且同时要保证,新的 Python 3 不会对已有的 Python 2 有任何的影响。
另外一方面,通过让 23 并存的实践,也是一种温故知新,让我们对环境这个概念有更深一些的理解。

准备工作

所谓的准备工作,就是 备份工作。你即使可能并不需要做这个操作,但也需要理解这个环节的意义。
因为要安装新的 Python 版本,我们会担心,安装的过程中,是否会把新版本的 Python 可执行文件放到操作系统的 $PATH 中。假设安装 Python 3 发生了这个情况,而且直接替换了这个路径 /usr/bin/python 上的文件,那么,我们再在 命令行窗口 输入 python 就不会进入到之前的 Python 2.7 环境中了。
所以,如果有必要,我们要将原来 $PATH 中对应的各个 python 文件进行一次备份。

注意:

  1. 一般来说,/usr/bin 这个目录是系统级目录,不要去改;而 /usr/local/bin 则是用户层面的目录,可以自己修改,修改的过程中,也不需要输入管理员密码进行校验。
  2. 有些可执行文件的路径,并非实体的,而是一个映射、快捷方式,比如上面截图中的 python3 的路径位置。

首先安装 brew

先安装好 MacOS 上的包管理软件 Homebrew (也叫 brew),它主要是基于 Ruby (跟 Python 类似的另外一种脚本语言) 与 Git 。

安装 Python 3

通过 brew 安装 Python 3 很简单,只需要在命令行中输入 brew install python3,等待安装完成即可。
不要直接下载 Python 的下载包进行安装,安装的过程中可能需要输入系统密码,也不清楚这种情况下的安装,会修改什么系统级的环境变量,或者导致其它什么潜在的问题。所以,直接下载一个 Python 的安装包,是不推荐的一种方法。

重新捋一遍

$PATH 是一个 列表,有先后次序的。
如果 /usr/bin/python (2.7 版本)/usr/local/bin/python (3.7 版本) 同时存在;在 $PATH 中,/usr/local/bin 的位置是在 /usr/bin 之前的 (安装 brew 之后默认应该也是这个情况),那么输入 python 进入的是 3.7 版本
上述这种情况,我们可以将 /usr/local/bin/python 直接重命名为 /usr/local/bin/python3,那么输入 python3 会进入3.7 版本,而输入 python 会进入默认的2.7 版本

看起来这个逻辑有些拗口,但是自己沉下心来想一想 (务必),会发现这并不复杂。如果有一种 『哇哦,原来是这样子呀』的感觉,那么,说明你对于 Python 的安装环境、以及操作系统中 PATH 的逻辑,已经掌握了。

最后

现在,Python 2 本来系统里就有了,Python 3 也已经安装了。
我们希望输入 python 的时候,进入 Python 2 (系统默认);输入 python3 的时候,进入 Python 3 (brew 应该会自动处理了)。
如果仍然有些问题,你也应该知道怎么处理了吧?就是要知道对应版本的 Python 的可执行文件的路径,然后做一个软链,放到$PATH对应的目录内就可以了。
不知道什么是 软链?它就是一个映射、快捷方式,你可以使用搜索引擎获得这个知识点。

其它有两个小地方需要注意:

  1. 如果只是尝试,不知道结果如何的,而且命令行窗口中提示需要输入密码的,要慎重一些。
  2. 当前命令行窗口,也是有一个 session (会话) 的概念,有些针对操作系统的修改,未必会直接生效,可能需要新开一个命令行窗口才能看到效果,这种情况比较少见。如果命令行窗口内的操作,有一些未生效的,排除 session 的问题,更多可能还是自己的问题,比如输入的命令、变量错了。

使用 pip

pip 是什么

pip 是 Python 的包(package)管理器,说到包管理器,前面的 brew 也是,但 brew 针对的是 MacOS 的,而 pip 则是 Python 专用的。
另外,pip 虽然管理 package,但 pip 本身也是一个package

后续再持续接触 Python 后,你可能会纳闷,package 不是应该在 Python 中被 import 吗?怎么可以在命令行中被直接使用呢?
Python 的 package 并不是说只能在 Python 内部使用,一个 package 也可以提供一个可直接运行的命令,它一般最终会对应到 package 内的某个函数。

如何安装 pip

curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py --user

注意(非常重要):

  1. python get-pip.py --user 后面增加一个 --user 的参数,可以让 pip 不安装在系统级的目录内,也就是说不需要输入管理员密码进行验证。
  2. python get-pip.py 中的 python 非常重要,你可以运行 which python 查看当前 python 的路径,因为这意味着将 pip 安装到当前对应的 Python 解释器的环境中。比如 python 对应了 2.7 版本,而你想安装 Python 3 的 pip,那么就应该是 python3 get-pip.py
  3. 同样,如果是多个 Python 版本共存的操作系统,各自的 pip 安装成功后,要分清直接使用 pip 对应的命令,是针对哪个 Python 版本的。如有必要,可以在对应的 $PATH 目录中对 pip 改名,比如 /usr/local/bin/pip 改为 /usr/local/bin/pip323 的 Python 版本共存,还是常见的,还有比较少见的是多个 Python 2 也共存的情况,这个时候 pip 指向具体 Python 版本的对应命令也应该进行改名,比如 pip2.7pip2.6 此类的名称。
  4. 注意: --user 可能会导致 package 里的可执行命令 (多数 package 里是没有的) 在 $PATH 中找不到,这时,就要去掉 --user,并且添加 sudo 重试。pip 作为一个开源的工具,又是一个极其常用的 module,使用 sudo 直接安装到系统文件夹中,也是没有什么副作用的。

使用 pip

比如我们要安装的一个 package 叫 requests,那么直接运行 pip install requests --user 就可以了,如果要指定版本 (比如是 2.22.0),那么直接运行 pip install requests==2.22.0 --user 。注意,是两个等号 ==,不是一个。
另外,在后面增加了 --user,跟最开始安装 pip 时候一样,避免 package 直接安装在系统级的目录下。

最后,有句话是老生常谈,但是太重要了,重要到就算现在不听,终究有一天,撞南墙了也会得出同样的结论: 注意 package 的版本!
在完成某个具体项目、产品的时候,如有必要,请务必记录并指定 package 的版本,以免后续部署时,package 的版本不对,导致整个程序跑不起来。
一般也不建议在产品处于运行的状态下去升级一个 package 的版本。你看,我们此处连如何使用 pip 去升级 package 的用法都不说呢……