基于项目,独立的环境

温故知新

Python 的环境就相当于 Python 解释器 + 默认的 (系统) package + 我们自己安装的 package,我们也另外介绍了 Module (Package) 对应到 sys.path 的寻址。
所以,自然会产生一个想法:能不能把所有的 package 统一安装到某个地方呢?如此一来,未来更换电脑设备、重装系统,重新载入需要的 Python 环境就很方便了。
不仅如此,按照这个思路,我们可以为不同的产品、项目,准备不同的 Python 环境。现在的我们可能对 package 的版本问题还没有直接的认知,但现实情况来说,如何处理 package 的版本、依赖,是绕不开的一个问题。

关于环境、package 依赖的解决方法,就是创建虚拟环境,如果打个比喻,就相当于虚拟机,虚拟机可以让我们在同一台设备上,跑多个操作系统:Windows、MacOS、Linux ...
Python 的『虚拟机』的构建会方便很多,本质上是处理掉一些约定的设定就可以了。
但我们需要注意,Python 虚拟环境 的构建,并非是 Python 的标配,在实践过程中,我们可能会通过 Docker 以及相关的脚本在服务器上搭建环境,未必会采用本文虚拟环境的思路,虽然基本的逻辑还是一致的。

我们在本课程中,某些地方采用了 Python 虚拟环境,是考虑到保持某个 Project 的隔离,以免污染了全局的 Python 环境,另外一方面,也定然会让我们这个使用的过程中,加深对 Python 环境 的理解。
对了,由于 虚拟环境 的存在,选择 Python 2 还是 Python 3,真要切换的时候,切换成本是很低的。

使用 pipenv

pipenv,项目网址为 https://github.com/pypa/pipenv,相当于 pip + env (environment 的缩写)的组合。我们通过在命令行窗口运行 brew install pipenv 就能完成 pipenv 的安装。

然后,我们用 pipenv 构建 Python 的虚拟环境。

第一步,进入 Project 对应的文件夹,cd 路径即可,如果文件夹的路径中包含空格等特殊符号,可以使用引号包裹路径,比如 cd "路径"注意: Project 的文件夹名称尽可能是英文字母组成,如果使用中文、空格、问号、& 等,可能会导致 pipenv 无法正常工作。

第二步, 运行 pipenv --python 2.7,就会自动创建 Python 的新环境。

环境创建成功之后,如果要安装 package,就不要再使用 pip install xxx,而是用 pipenv install xxx
关于 pipenv 的其它具体用法,请自行了解,除了到 pipenv 项目主页查看帮助之外,也可以直接运行 pipenv --help 查看。一般来说,pipenv shell 可以进入当前环境对应的命令行环境,然后再输入 python,就能进到当前环境 Python 的交互命令状态,如果需要退出则输入 exit (exit 后面没有括号) 并敲击回车键。

注意: 使用 pipenv install xxx 的时候,很可能会出现等待时间超长的问题,可以且不管它,直接先 pipenv shell 进入对应的命令行的环境,然后再 pip install xxx 就可以了。毕竟,我们的目的只是为了获得虚拟环境,能隔离环境、安装 package 就足够了。

对 PyCharm 的再配置

因为不是通过 PyCharm 创建的项目,没有在最开始就配置 Python 虚拟环境,所以,此时需要对 PyCharm 进行再配置,主要是设定对应的 Python 解释器
首先进入Preferences (快捷键为 Comand + , ),找到 Project 对应的设置,以及其中的 Project Interpreter (如下图所示):

选择 Pipenv Environment:

等待 Python 环境的创建、载入:

新的 Python 解释器就上线了:

其实也可以先在命令行里运行 pipenv --py 找到当前 Python 环境的解释器路径,然后为 PyCharm 的项目手工添加指定的解释器路径。
我们去配置这些时,应该要清楚,其本质的逻辑是什么。 IDE 作为一个辅助性工具,在这个工具进化的过程中,会不断地、甚至主动地为使用者 (自动化地) 解决问题,表面上是提升了用户体验,但对于新手而言,可能会有负面的作用。

一反 《FirstWeb》中的常态,到现在,我们一行代码都没有开始写,就是在不断介绍 Python 的基础,甚至基础之前的基础。
从我个人的经历回过头来看,这些反倒是最宝贵的。如果真有再来一次的机会,这些 How & Why 的基础逻辑,可以避免太多初期时候的时间浪费。
请恕唠叨了,亦深知初始这些内容可能的枯燥,甚至就像老生常谈,但务必多一分心情去理解。后面还有好多基础内容,先不着急写下第一行代码,一般也不过是 print('Hello World') 之类的,甚至有些教程可以花一大篇幅的内容去教人写 print ,我们不要这样子。