Python 的环境

本篇内容,有些重复自 《FirstWeb》『部署网站到服务器』『服务器常用命令』关于 PATH 的说明,建议也可以先重新翻阅这两部分内容,以温故知新。

命令行、终端 (Terminal)

有些时候,我们说 在命令行窗口中操作,或者 在 Terminal 中操作,其实说的是同一件事情。Terminal.app 是 MacOS 自带的,同样还有第三方的命令行 App,比如 iTerm,它在功能上可以取代系统默认的 Terminal.app

你可以在 启动台 里搜索 Terminal,中文翻译为 终端 (有点奇怪的翻译)。

命令行的操作方式,是我们以后会经常用到的,它是一种『远古时代』流传下来的『人机交互』方式,有输入、有输出
命令行窗口本身就是一个 交互环境,运行一些直接的命令,或者调用具体的某个 App。在这个 交互环境 下,可以进入其它的 交互环境,比如我们输入 python 的时候,就会进入 Python 的 交互环境,然后再输入 exit() (这是 Python 退出的语法) 或者 快捷键 Control+Z (不推荐,当前程序只是被挂起,并未真正退出),就会退出 Python 的环境,重新回到命令行窗口默认的 交互环境

什么是 『环境』

环境 并不算一个特定的技术性术语,在实际的语境中,应该不用特别解释,就能明白它所代表的含义。
为什么说『环境』这个名词并非特定的呢?是因为在使用这个名词时,是比较笼统的概念

  • 上文提到的 交互环境 本身也是一个环境
  • 当我们说 某个项目的环境,是指当前项目的技术路线、依赖的库;
  • 当我们说 某个程序的环境,可能又是指当前程序在运行过程中,一个系统全局的各种配置项;
  • 当我们电脑重装的时候, 会说要安装下环境,这又是一个复合的概念,是指将自己开发需要用到的各种依赖包、软件全部安装起来,让当前电脑处于一个可让自己工作的状态。

作为基础,我们先说说 命令行窗口 本身的环境
我们先输入 echo $PATH,就会获得操作系统的 PATH 环境变量:

PATH这个变量实际上是一个列表性质的,多个路径之间使用 : 分隔,比如 /usr/local/bin:/usr/bin:/bin 这个 PATH,实际上是指:

/usr/local/bin
/usr/bin
/bin

此时,比如我们输入 python,系统会依次寻找下面路径的『程序』进入:

/usr/local/bin/python
/usr/bin/python
/bin/python

匹配到了第一个,就会运行这个程序,也就是进入了 Python 的 命令交互环境

如果是 python /my_path/where_is/my_script.py,则是对应下面的匹配逻辑:

/usr/local/bin/python  /my_path/where_is/my_script.py
/usr/bin/python  /my_path/where_is/my_script.py
/bin/python  /my_path/where_is/my_script.py

python 对应到的实际路径如果是 /usr/local/bin/python,那么 /usr/local/bin/python /my_path/where_is/my_script.py 的意思就是:运行 /usr/local/bin/python/my_path/where_is/my_script.py参数,在 python 这个『程序』中,这个参数的意义是运行这个路径上的脚本文件。
就像 echo $PATH 一样,echo 是命令,而 $PATH 是参数。

Python 的环境

为了便于理解,我们把 Python 相关的『环境』简单地分为两类:

  1. Python 相对于操作系统,其所处的环境;
  2. 具体 python 代码、文件,相对于 Python (解释器),其所处的环境。

甚至可以更简单地将上述两者理解为: 1. 安装 Python; 2. 运行 Python。


我们还需要理解一个概念,就是Python 解释器 (Interpreter),可以把它当做最纯粹的 python 可执行程序,一个 .py 文件实际上是由 python 程序执行的,这个可执行程序的完整路径是 /usr/bin/python (视操作系统 PATH 的匹配对应),而不是具体 .py 文件的路径。
当我们写了一个 Python 脚本(比如 my_python_script.py),这个脚本文件也叫 Python 程序,而更准确的说法,应该是 使用 Python 语法写下的脚本并需要 Python 解释器运行的脚本文件,但日常交流,这样的说法肯定是拗口的不行。
Python 的解释器,是一个 可执行文件,而且尺寸其实很小的,压成 zip 文件,也就 1MB 多一些。而 Python 2 还是 Python 3,最核心的不同来看,就是解释器这个可执行文件的不同。


『 Python 的环境』有两个层面的意思:第一层面,就是对 解释器设置,也就是 Python 解释器本身;第二层面,则是在第一层的基础上,当前产品需要哪些 package。
Python 解释器的设置,一般有两件事情要做:

  1. 直接在命令行窗口中输入 python 或者 python2python3 可以匹配到对应版本的 Python 解释器;
  2. 后续安装 Python 的 package 时,知道安装到什么地方,以及引入这些 package 应该从什么地方 import 。

这两件事情,由于系统中默认安装了 Python,或者自己一键式地安装 Python,这些默认都会被自动处理掉。但另一方面,这些基本逻辑如果没有搞清楚,很容易出问题。

简化的结论

上文一堆枯燥的辞藻,或许还有些晦涩,我们就再简化之,给个简单的结论。
大多数时候,我们讲的 Python 环境,就是指: Python 解释器 + 默认的 (系统) package + 我们自己安装的 package
所谓的 Python 解释器,就是 裸Python
如果只有裸Python,Python 的功用就受到了巨大限制,因此一些常用的 package 由系统默认提供了,比如 random (产生随机)、re (正则表达式) 、os (操作系统相关)。
但系统提供的 package 总是不够用的,这就需要第三方的支持,比如 requests(处理 Web 请求) 这个第三方 package 就比默认提供的标准库好用、常用。

其它小结

我们花大篇幅去强调关于 Python 环境 的基本逻辑,而不是 step by step 的方式,让大家直接搭建好环境,很重要的原因,是为了避免未来的混乱。
作为新手而言,固然在自己不清楚的领域,直接听从入门老师的指挥,是最高效的做法。
但代码的世界,是讲逻辑的,那些第一步、第二步的操作,都有为什么的归因。不理解这些归因,直接 step by step,搭建环境是很容易的,但后续遇到问题了呢,自己怎么解决?
有个常见的现象,比如安装某个 package 失败,命令行窗口中明明给出了错误信息 或者提示 将错误信息记录在某个错误日志了,很多人首先想到的并不是去看这个错误日志,而是先去搜索引擎搜索 can't install xxxx,这样的关键词。

作为新手,我们也要保持一种思考。
MacOS 目前(2019 年) 默认内置了 Python 的环境,且是 2.7 的版本,如果要创造一个 Python 3 的环境,又不清楚背后的逻辑,很容易顾此失彼,为了一个新版本的 Python 环境,而导致系统内其它机制的失效,甚至会导致某些看起来毫无关联的 App 直接无法启动。特别是初学者,使用搜索引擎,涉及到这某些 How To,可能好几篇文章一起融合起来尝试,结果,系统的环境,在某个环节中,就被破坏了。
简而言之,在命令行中,如果是 sudo开头的命令,需要输入密码进行下一步的操作,自己处于完全新手状态,又是面对 step by step 类型的教程,最好再多一分谨慎
起码,不要尝试去替换操作系统默认提供的一些引擎、环境。我们在后面一节中,会讲 《如何搭建环境》,其中有『如何让 Python 2 与 Python 3 共存』,在 Python 2 的 MacOS 上学习 Python 3 并不需要把系统内的 Python 2 升级到 Python 3。