在上一章里,我们讨论了构建开发环境的基本步骤,如选择操作系统、选择集成开发环境等。现在我们可以着手编写代码了,但要能运行和调试程序,还需要指定Python运行时(或者称之为解释器)。
特别地,如果你使用的开发工具是VS Code,那么这一步是必须的:因为VS Code并不是只为开发Python应用程序而设计的,它支持好多种开发语言。因此,要使得VS Code知道你的工程项目是基于Python的,就必须为它指定Python运行时。
Python有两个主要的运行时版本,Python 2.x和Python 3.x。Python 3.x是对2.x版本的破坏性升级。当前,需要在3.x版本下运行的应用程序和组件越来越多了,然而,像MacOs或者Ubuntu这样的操作系统,它的一些老旧版本仍然依赖Python 2.x来运行一些核心功能,比如包管理。因此,在这些系统上,Python 2.x仍然是缺省安装的Python运行时版本。

这会是你在开发Python应用时的将会遇到的第一个问题:你想要开发一个Python应用程序,使用了最新的Python版本,有着大量酷炫的新特征和新功能。但当你的应用程序部署时,可能被部署到各种各样的机器上,这些机器上缺省安装的Python版本,并不是你开发时指定的版本。如果强行升级系统缺省安装的Python版本,则可能会破坏其它应用程序;而如果不进行升级,则又没办法运行你的程序。
即使目标机器和你的应用程序使用了同样的Python版本,类似的冲突还可能发生在其它组件上。比如Django是Python社区中最负盛名的web开发框架。它依赖于SQLAlchemy – Python社区中另一个同样颇负盛名的开源orm框架。如果你的程序也依赖于SQLAlchemy,并且你使用了SQLAlchemy 1.4以上的版本,而Django使用了它的早期版本,那么很不幸,这两个应用程序将无法共用同一个Python环境: SQLAlchemy 1.4相对于之前的版本,是完全不兼容的破坏性更新。
这类问题被称之为依赖地狱。依赖地狱并不是Python独有的问题,它是所有的软件系统都会面临的问题。
1. 依赖地狱
在构建软件系统时,通常都会涉及功能复用的问题。毕竟,“重新发明轮子”是一种不必要的浪费。功能复用可能发生在源代码级别、二进制级别或者服务级别。源代码级别就是在我们的工程中,直接使用他人的代码源码;二进制级别是指在我们的应用中使用第三方库;服务级别的复用,则是程序功能以服务的方式独立运行,其它应用通过网络请求来使用这种功能。
当我们使用二进制级别的复用时,就常常会遇到依赖地狱问题。比如在上面Django的例子中,如果没有一种方法可以向Django和你的应用分别提供不同版本的SQLAlchemy,则这两个应用将无法同时运行在同一台机器上。
依赖地狱并不是Python独有的问题。所有的程序开发语言都会遇到类似的问题。解决这个问题的方法之一,就是将程序的运行环境彼此隔离起来。比如,应用程序所依赖的第三方库,不是安装到系统目录中,而是安装到单独的目录中:比如,随着该应用程序一起安装到该应用程序所占的目录中,并且,只从这个目录中加载依赖的第三方库。

Python解释器本身也可以看成一个普通的应用程序。因此,当我们安装一个Python应用程序时,可以将该程序依赖的Python运行时,及相关的第三方库,都安装到一个单独的目录中。这样,当我们运行该应用程序时,就从该目录中启动Python,如果Python只从(或者优先)该目录加载第三方库的话,我们就实现了某种程度的隔离。这种思想,就是虚拟运行环境的思想,它是解决Python依赖地狱问题的一个主要方法。
既然我们提到了“隔离”一词,我们不妨再稍稍引申一下。在第二章我们提到了虚拟机和Docker容器,这些是解决资源冲突,对资源进行隔离的方法。现在,通过容器以(微)服务的方式来部署Python应用程序也越来越常见,其中也有简化安装环境、避免依赖地狱等方面的考虑。
在这一章我们主要讲如何构建虚拟运行环境,这样可以完全解决运行时与其它应用程序之间可能发生的依赖地狱问题。然而,依赖地狱还有其它多种表现形式,我们后面还会在讲述Poetry那一章再探讨这个问题。
2. 使用虚拟环境逃出依赖地狱
Python的虚拟环境方案可谓源远流长,种类繁多。如果你接触Python已经有一段时间了,那么你很可能听说过annaconda, virutalenv, venv, pip, pipenv, poetry, pyenv, pyvenv, pyenv-virtualenv, virtualenvwrapper, pyenv-virtualenv wrapper等相似概念。

在上面这些令人眼花缭乱的词语中,Annaconda(以下简称conda)和Virtualenv是一对儿对手,Pipenv则和Poetry相互竞争。而Venv则是其中血统最为纯正的一个,得到了Python官方的祝福。
pipenv和poetry,尽管常常被人在讨论虚拟环境的场合下提起,也确实与虚拟环境相关,但他们所做的工作都远远超过了虚拟环境本身——它们的主要功能是提供依赖管理,poetry还提供了构建和打包功能(我们将在Poetry那一章中来详细介绍)。
venv不是一个独立的工具,它只是一个模块。venv是从Python 3.8起,标准库里提供的一个模块,你可以使用python -m venv来运行它。它的目标与virtualenv比较接近,但只提供了virutalenv的一个命令子集。由于它是标准库提供的,因此许多工具

本文讲述了在Python开发中如何指定Python运行时,尤其是在VSCode中设置Python环境。重点介绍了Python的两个主要运行时版本以及依赖地狱问题,探讨了虚拟环境如conda、virtualenv和pipenv在隔离依赖和解决依赖冲突中的作用,以及如何配置VSCode以正确使用Python解释器。
最低0.47元/天 解锁文章
1504





