入门 Python 的虚拟环境管理

  • Post author:
  • Post category:python




1 概念介绍



1.1 Python 解释器

在开始学习使用 Python 时,我们一般会直接在电脑上安装一个全局的 Python 解释器。后续也一般就是用这个解释器来运行 Python 代码。

这个 Python 解释器是有不同的版本的,比如 Python2.7 跟 Python3.7 等。

这里要了解的概念是:Python 解释器。

现在想象这样一个场景,你本地一直用 Python3.7 在学习,突然在网上发现一个很有意思的 Python 工程,下载下来之后,发现运行报错,原因是这个工程的作者当初是使用了 Python 2.7 来编写运行的。

这个时候岂不是超级无敌麻烦, 难道为了体验这个有意思的 Python 工程,就要重装我的全局的 Python 解释器?



1.2 Python 依赖

我们在写 Python 代码的时候,比如 import os 之后,那么我们的 Python 代码的运行,就依赖了这个 os 的模块。依赖其实就可以理解为是那些我们需要引用的模块、包。

像 os 这个模块是 Python 自带的,因此我们不需要额外下载安装。而像 requests 这个常用的库,我们是需要自己下载安装的。为了方便使用,就有了很多所谓的依赖的安装与管理工具,比如我们常见的pip。

这里要了解的概念是:(1)依赖(2)安装与管理工具。

现在想象这样一个场景,你从网络上下载了两个 Python 工程准备来运行学习,分别记作工程 A 跟工程 B。工程 A 依赖了 C 库的 1.0.1 版本,工程 B 依赖了 C库 的 2.0.1 版本,且 C库 的这两个版本不兼容。

这个时候岂不是超级无敌麻烦, 工程 A 跟 工程 B 就没办法同时运行了。



1.3 Python 虚拟环境

上述两个”超级无敌麻烦”的场景,在实际的团队协作与项目工作中是非常常见的.为了解决这些问题,Python 的虚拟环境机制也就应运而生。

所谓的虚拟环境,可以理解为就是创造了不同的 Python 环境,来达到 Python 解释器隔离跟依赖隔离的作用。也就是可以在同一个电脑上,使用不同的 Python 解释器,并且避免依赖冲突的问题!

有了虚拟环境,我们可以保证各个 Python 工程的运行互不干扰,也可以保证协作项目在每个协作者自身开发环境的统一。



2 Python 虚拟环境的管理方案

这块的工具可太多了,这里对常见的管理方案(工具)进行介绍跟对比。



2.1 内置 venv

在 Python 3.3 版本及以后,内置了一个模块 venv。如果你看到网络上有讲一个工具叫做 pyvenv,其实就是 venv!不过 pyvenv 的用法在 Python 3.6 就移除了。

创建虚拟环境的命令如下。

python -m venv /path/to/new/virtual/environment

此时就会以你执行上述命名的 Python 解释器版本,来创建一个虚拟环境,目录结构大致如下。

├── bin
│   ├── Activate.ps1
│   ├── activate
│   ├── activate.csh
│   ├── activate.fish
│   ├── easy_install
│   ├── easy_install-3.8
│   ├── pip
│   ├── pip3
│   ├── pip3.8
│   ├── python -> /Users/xxx/bin/python
│   └── python3 -> python
├── include
├── lib
│   └── python3.8
│       └── site-packages
└── pyvenv.cfg

具体的用法可以

python -m venv -h

查看,更多信息可参见

官方文档

的描述。

在创建了虚拟环境之后,如何使用虚拟环境?

  • 在终端上使用

    在终端上需要进行手动激活,比如我这边用的是 macOS ,那么就使用

    source <venv>/bin/activate

    来激活虚拟环境。

    退出该虚拟环境则使用

    deactivate

    或者

    exit

    或者直接关闭终端。

  • 在 PyCharm 等 IDE 上使用

    会识别 venv 虚拟环境,可以在软件设置中修改使用的虚拟环境。

不过使用 venv 模块存在一个令人头疼的问题:如果我们有多个项目,那么就会存在多个由 venv 创建的虚拟环境,因此我们无法做到统一集中管理。

所以,Python 社区的里的其他方案也意识到了这一点,也都具备了统一在一个命令中管理虚拟环境的功能。



2.2 virtualenv

官网:https://virtualenv.pypa.io/en/latest/

我们从官网介绍可以看到 venv 的功能是 virtualenv 的一个子集,且列举了 venv 的几个不足。

  • is slower
  • is not as extendable
  • cannot create virtual environments for arbitrarily installed python versions
  • is not upgrade-able via pip
  • does not have as rich programmatic API

直观上对比,venv 跟 virtualenv 都提供了环境隔离的功能,没有提供依赖安装和依赖版本解析的功能(后面介绍其他工具会提,可先不关注)。虽然 venv 只支持 Python 3.x,不支持 Python 2.x ,但随着 Python 的发展,这个也不太是问题了。

virtualenv 用法跟 venv 很类似,创建虚拟环境的命令如下。

virtualenv /path/to/new/virtual/environment



2.3 conda

Conda(conda才是包管理器,miniconda和anaconda是内置了conda的Python发行版)是环境隔离和依赖安装的一体化解决方案。

Conda 除了能安装 Python 依赖库或包之外,还能安装其他语言的一些依赖;比如有的 Python 需要调用到 C/C++ 的库,就比较适合用 Conda。

Anaconda 中不仅内置了一个 Python 解释器,同时还内置了许多常用的数据科学软件包或工具。因为自己不是从事数据科学相关领域的,所以后面也一般没有使用 Anaconda 了。



2.4 pipenv

pipenv 跟下面要介绍的 Poetry 较类似。可以理解为 Pip + pyenv + resolver + virtualenv 。其中 pip 提供了依赖安装的能力, pyenv 提供了使用多 python 解释器版本的能力,而 resolver 提供了依赖版本解析的能力。据目前了解,Pipenv 先发优势所以更加流行一些,但是 Poetry 的易用性更加,不断追赶上。

pipenv 的文档可见:https://pipenv.pypa.io/en/latest/

我在一个项目中使用了 pipenv ,常用方法有以下这些。

# 安装pipnev
pip install pipenv

# 创建虚拟环境
pipenv install  # 虚拟环境如果不存在的话,会自动创建
pipenv --python 3.8  # 可以指定python版本。 pipenv 会自动扫描系统寻找合适的版本信息,如果找不到的话,同时又安装了 pyenv, 它会自动调用pyenv下载对应的版本的python 

# 查看虚拟环境
 pipenv --venv
/Users/userisme/.local/share/virtualenvs/test_project-wL5os1_R

# 激活虚拟环境
(base) userisme-MC0:test_project userisme$ pipenv shell
Launching subshell in virtual environment...

The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
For more details, please visit https://support.apple.com/kb/HT208050.
bash-3.2$  . /Users/userisme/.local/share/virtualenvs/test_project-wL5os1_R/bin/activate

# 退出虚拟环境
(test_project) bash-3.2$ exit
exit
(base) userisme-MC0:test_project userisme$

# 安装依赖到虚拟环境
pipenv install 
pipenv install requests==2.13.0  # 安装指定版本

# 依赖安装
pipenv install  # 会自动安装Pipfile中记录的依赖

# 其他
pipenv install --dev  # 可区分开发依赖
pipenv graph  # 图形显示包依赖关系
pipenv uninstall --all  # 删除所有的安装包
pipenv install -r path/to/requirements.txt  # 安装requirements.txt中的依赖

# 从Pipfile和Pipfile.lock文件来生成requirements.txt
pipenv lock -r  # 生成requirements.txt文件
pipenv lock -r -d  # 生成dev-packages的requirements.txt文件



2.5 poetry

poetry 使用

pyproject.toml

来做依赖说明(还有其他作用,这里不涉及就不提了)。poetry 除了依赖管理,还具备了打包的能力,不需要额外安装 setuptools 来发布你的安装包。

基础的用法可以查看文档:https://python-poetry.org/docs/basic-usage/

大概看了一眼,讲的还是比较细致了:

  1. 包含了常见命令跟常见的使用场景
  2. 如果看到版本号限定为

    ^2.1

    ,其代表的意思是 (>= 2.1.0 , < 3.0.0)。
  3. 需要注意的是,现在最新版本的 poetry 是不支持 Python2.7 了。大家还是使用 Python 3.+ 吧。



2.6 pdm

大家可以看 github上 的介绍:https://github.com/pdm-project/pdm

这个作者是中国人,其本身也是 pipenv 的维护者~



2.7 大致结论

虽然 PDM 我还没用过,但看了下他的 blog ,其观点我很赞同: 其实目前以上的 Python 的工具,基本上就是围绕着虚拟环境管理、依赖管理、打包发布这三块在解决问题,提升用户体验。不同工具有其侧重点跟覆盖范围,大家还是全凭需求来选择!

如果你只是简单了解学习下 Python ,看起来是使用自带的 venv 就行。

如果你是做科学计算的库,可能较适合用 conda(Anaconda、miniconda)

如果是同时参与多个 Python 项目开发的,需要使用虚拟环境的,比较推荐用 Poetry 。

如果你都不喜欢,你完全可以弄个虚拟机或 Docker ,然后随便搞。



3 关于项目协作开发中的依赖问题

项目的依赖应当明确地写在项目的依赖文件中。通常在实际的开发、测试、生产环境中,为了保持依赖完全一致,通常是将依赖信息固定写入到 requirements.txt 中。使用命令如

pip freeze > requirements.txt


这里随便提一下 install_requires 这个东西,由于个人不了解,就不多讨论了。它跟 requirements 的比较可以参考:https://packaging.python.org/en/latest/discussions/install-requires-vs-requirements/ 。



4 参考文档

这篇文章个人感觉内容丰富,值得一看。

细数 Python 虚拟环境的管理方案



版权声明:本文为wzy0754原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。