什么是 Python 虚拟环境

安装不算完事,Python 虚拟环境必须了解一下。

什么是环境

既然有所谓的 虚拟环境(Virtual Environment),那么首先有必要解释一下,什么是环境。

这里的环境,指的就是 Python 代码的运行环境。它应该包含以下信息:

  • Python 解释器,用哪个解释器来执行代码?
  • Python 库的位置,该去哪里 import 所需要的模块呢?
  • 可执行程序的位置,比如说安装了 pip,那么 pip 命令是在哪里呢?

其中第 1 个是最主要的,后面 2 个基本是围绕它确定的。

如果看了我在 安装 Python 详解 里对安装后的文件夹的说明,应该很清楚了,就是:

  • python.exe
  • Lib 文件夹,包括其中的 site-packages
  • Scripts 文件夹

sys.path

当我们说包的路径就在 Libsite-packages 文件夹里的时候,虽然大多数的情况下就是这样的,但是实际上并不准确。

包的搜寻路径是通过 Python 系统中的一个变量决定的,也就是 sys.path,我们先来打印一下看看:

>>> import sys
>>> from pprint import pprint
>>> pprint(sys.path)
['',   # 注意,别忽视了第 1 个
 'C:\\Users\\Davy\\AppData\\Local\\Programs\\Python\\Python38\\python38.zip',
 'C:\\Users\\Davy\\AppData\\Local\\Programs\\Python\\Python38\\DLLs',
 'C:\\Users\\Davy\\AppData\\Local\\Programs\\Python\\Python38\\lib',
 'C:\\Users\\Davy\\AppData\\Local\\Programs\\Python\\Python38',
 'C:\\Users\\Davy\\AppData\\Roaming\\Python\\Python38\\site-packages',
 'C:\\Users\\Davy\\AppData\\Local\\Programs\\Python\\Python38\\lib\\site-packages']
>>>

pprint 是内置的 pretty-print 模块,可以自动换行,让打印结果好看一点。

注意:第 1 项是一个空字符串,它代表的是当前路径,也就是你启动程序的地方。比如说,我们默认情况下进入命令行就自动进入到当前用户的目录,例如 C:\Users\Davy,那么当前目录就是这个。

如果你还感到疑惑,可以用下面的语句打印出绝对路径:

>>> import os.path
>>> os.path.abspath('')
'C:\\Users\\Davy'

除了第一项,这个列表里最常用的就是最后一项,这个在 Python 安装详解 中有过说明。

什么是虚拟环境

知道了什么是环境,再来理解什么是虚拟环境就非常容易了。

简而言之,虚拟环境就是 Python 环境的一个副本。

要得到这么一个副本,首先:

  • 要给它单独找个文件夹存起来
  • 要给它取个名字

这个文件夹的名字也就是这个虚拟环境的名字,在这个文件夹下面有这些东西:

  • 一个 python.exe
  • 一个 Scripts 目录
  • 一个 Lib 目录

这里和普通环境有 2 点不一样的地方:

  • python.exe 也放在了 Scripts 目录下面(原因下面会讲)
  • Lib 目录下面只有 site-packages 目录

让我们来试一下。

venv 模块

在 Python 2.x 的时候,创建虚拟环境还需要安装第三方的 virtualenv,但是自从 Python 3.3 版本之后,标准库里内置了 venv 模块,可以用来创建虚拟环境。

在命令行中使用下面的命令来快速创建一个虚拟环境:

C:\Users\Davy>python -m venv venvdemo

上面的命令会在当前目录下,新建一个名为 venvdemo 的虚拟环境。里面的文件夹:

虚拟环境目录

其中 Include 基本不用管,Lib 目录下也没什么特别的,主要就是 Scripts 目录:

虚拟环境目录Scripts

其中多出了 activatedeactivate 用来 激活去激活 虚拟环境。

activate 有多个后缀的文件,适配多个环境,敲命令的时候不需要带后缀

让我们来激活试试:

C:\Users\Davy>venvdemo\Scripts\activate

激活虚拟环境

注意到一点,激活的时候我们需要指定 activate 完整的路径,因为它所在的目录并不在 PATH 环境变量之中。

激活之后,我们就进入了虚拟环境,这时候不管是执行 python 还是 pip 针对的都是虚拟环境里面的。

其实这也没什么神奇的操作,激活只不过就是把虚拟环境的 Scripts 目录临时添加到了 PATH 环境变量的第一位。

虚拟环境的环境变量

这里也解释了,为啥要把 python.exe 也放到了 Scripts 目录下,因为这样只需要加一个路径到环境变量中即可。

同时这也提醒我们注意,不是只有激活才能进入虚拟环境,我们如果把当前路径切换到了虚拟环境的 Scripts 目录下,启动 python 也是在虚拟环境中了。

继续打印一下 sys.path 看看:

(venvdemo) C:\Users\Davy>python
Python 3.8.1 (tags/v3.8.1:1b293b6, Dec 18 2019, 23:11:46) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from pprint import pprint
>>> import sys
>>> pprint(sys.path)
['',
 'C:\\Users\\Davy\\AppData\\Local\\Programs\\Python\\Python38\\python38.zip',
 'C:\\Users\\Davy\\AppData\\Local\\Programs\\Python\\Python38\\DLLs',
 'C:\\Users\\Davy\\AppData\\Local\\Programs\\Python\\Python38\\lib',
 'C:\\Users\\Davy\\AppData\\Local\\Programs\\Python\\Python38',
 'C:\\Users\\Davy\\venvdemo',
 'C:\\Users\\Davy\\venvdemo\\lib\\site-packages']

可以看到相对于上面普通的系统环境,最下面的两条发生了变化,注意其中的第 4 条路径 'C:\\Users\\Davy\\AppData\\Local\\Programs\\Python\\Python38\\lib',它正是标准库的路径。

我们在执行去激活的时候,就不用再指定完整的路径了。

为什么要有虚拟环境

当我们安装一个 Python 程序或者库的时候,一般情况下我们虽然是想要安装 1 个包,比如说, pip install django。然而实际安装的都是一堆包。这些包默认都会安装到 Python 环境的 site-packages 目录下面。

虚拟环境pip
下次再安装其它包时,也是如此。因为同一个库,只能在一个环境中存在一份,那么这其中如果发现了某个依赖包已经存在,只能大家公用。

这样下去,说不定哪一天这中间就出现了版本不兼容。

使用虚拟环境

因为虚拟环境的必要性,现在大多数的 Python 开发工具都支持虚拟环境的相关操作。

虚拟环境配置-pycharm

具体每个工具有所不同,但是一般只需要注意一点即可:指定虚拟环境中 python.exe 的位置。一旦确定了它的位置,就确定了环境的位置。也就不用每次都去激活。

仔细观察,虚拟环境中的 python.exe 和系统中的 python.exe 并不完全一样。

保存虚拟环境

我们知道在使用 pip install 的时候可以通过 -r 选项指定一个 requirements 文件,这样就能批量安装所有依赖。

requirements 里面可以精确的指定安装包版本,有效地避免不兼容问题。

执行 pip freeze 可以把当前环境安装的包以 requirements 的格式输出。

(venvdemo) C:\Users\Davy>pip freeze
asgiref==3.2.3
Django==3.0.3
pytz==2019.3
sqlparse==0.3.0

把输出结果保存到文件中就可以了,这样我们就精确的得到当前环境的版本信息,可以再其它地方重建这个环境。


文章内容虽基础,整理发布不轻松

如果看过有帮助,不妨 点赞 + 关注,谢谢!

Davy
Davy
学习📚 技术👨‍💻 投资📈

一些心得体会,希望能对你有所帮助🚀。