**本文将介绍 Anaconda 的进阶使用:用 conda 配置虚拟环境、 package(安装包)的管理、以及导入或导出虚拟环境。
一、为什么要配置虚拟环境?
既然 Anaconda 已经安装了这么多工具库(或者说 packages),做到了“开箱即用”,那直接在上面开发就好了,为什么还要建立虚拟环境呢?这个疑问可能是很多人刚认识虚拟环境时的第一反应。
我们先来看看虚拟环境的使用场景。设想一下:你有一个应用,需要 NumPy 1.18.1 以上版本,而另一个应用使用的是 NumPy 1.15.1,你要如何同时使用两个应用呢?
你可能会说,不是越新的越好吗?一律用最新版本的 NumPy 就好了。
不一定哦,如果都用最新版本,有时可能会出现不兼容的情况。在库的开发中,很多库都调用了一些其它的库,这样不需要重复造轮子。比如说某个库 A 开发时是基于 NumPy 1.15.1,如果 NumPy 升级中对一些函数做了修改,那么库 A 调用 NumPy 这些函数时可能会出现问题,导致不兼容。举个例子,早段时间我安装了 Jupyter Notebook 的扩展 jupyter_contrib_nbextensions,这样可以让 Jupyter Notebook 页面有更多功能,比如显示目录。在使用时,发现命令行终端老在报提示信息,“Config option ‘template_path’ not recognized by …”。在网上搜索,发现原因在于 jupyter_contrib_nbextensions 的依赖库之一 nbconvert 是 5.6.x 版本,而新版本 Anaconda 中安装的 nbconvert 是 6.x 版本。有一个文件夹在两个版本的 nbconvert 中命名分别是 ‘template_paths’ 和 ‘template_path’,就是这一个字母之差,就识别不出来。解决方法是重新安装,把 nbconvert 版本降到 5.6.1。这样 jupyter_contrib_nbextensions 的问题是解决了,但是可能其它库是基于 nbconvert 6.x 开发的,那又会出现新的问题。
Anaconda 的默认环境,叫 base,这个环境中已经安装了一些 packages。打个比方, base 环境就像一个大车间,里面已经有了各种工具,大家都可以用,但是每个工具只有一种型号 ( 每个 package 只能有一个版本 )。
那如果我需要用不同的型号呢?新开一个空的小车间(虚拟环境),按自己的需要存入工具,这样可以满足对于特定型号工具(不同版本的 package)的要求。不同的车间(虚拟环境)在不同位置,它们互不联系,因此互不影响。
我们也常会看到建议:开发自己的程序时,尽量建立一个虚拟环境。 为什么呢?这篇文章 提到,因为 base 环境中的工具库太多,其实开发时只需要一小部分。建立虚拟环境的好处,一是精简:只安装自己需要的库。二是稳定:安装 package,升级 package 等,都只在虚拟环境。换言之,如果不同的 package 因为版本不兼容,出现问题,再新建一个虚拟环境,而 base 环境不会受到影响。如果别人需要运行你开发的程序,可以把虚拟环境中的 packages 版本以列表的形式打包,随代码一起发过去(这就是后面会介绍的导出或导入虚拟环境),这样对方也可以在相同的环境配置中运行。
二、配置清华源
配置清华源,就是把 conda 中 package 的下载地址,改为清华镜像站,这样下载安装包速度更快。前面提到,新建虚拟环境相当于新开一个空房间,里面没有东西,因此,我们要在虚拟环境中安装需要的库,配置清华源可以加快这一安装进程。
清华镜像站-anaconda镜像页 上有配置指南,步骤如下:
1.Windows 用户无法直接创建名为 .condarc
的文件,可先执行 conda config --set show_channel_urls yes
生成该文件之后再修改。
2.到电脑的“用户”文件夹中,找到 .condarc
文件并打开(可以用 VSCode 或 记事本 打开),把 清华镜像站-anaconda镜像页 上的 condarc 配置语句复制进去即可。
3.然后,在 Anaconda Prompt 中运行 conda clean -i
清除索引缓存,保证用的是镜像站提供的索引。
执行完上述操作后,输入 conda info
,在 channel URLs 一项中,发现地址从原来的 repo.anaconda.com 换成了清华镜像站地址,如下图所示:
channel URLs
注:网上教程介绍的 另一种方法 是在 Anaconda Prompt 中修改,语句为
conda config --add channels https://……
,我试了一下,是把清华源链接添加在.condarc
文件 的 “channels” 一项中。而清华镜像站的教程是 “channels” 项保持不变,后面添加了两项:“default_channels” 和 “custom_channels”,用于存放清华源链接。两种方法是否相同,还是有什么区别,我也不知道(欢迎指教,谢谢!),我参考的是清华镜像站的教程。
三、如何配置和使用虚拟环境
3.1 虚拟环境基本操作
下面以例子来说明怎么建立、使用或是删除虚拟环境。比如:想新建一个名为 ‘pytest’ 的虚拟环境,打开 Anaconda (Powershell) Prompt,输入语句:
(1)新建虚拟环境:conda create -n pytest
(2)查看已配置环境列表(显示在 Anaconda 中配置的所有环境) :conda env list
或者用 conda info -e
(3)进入(激活)虚拟环境:conda activate pytest
可以看到,命令行开头的内容由 (base) 变成 (pytest)。用 conda list
查看 packages(安装包)列表,发现此时的虚拟环境是空的,没有安装 package。用 conda install pkg_name
可在当前虚拟环境安装需要的包。
(4)退出虚拟环境:conda deactivate
注意:并不是删除虚拟环境,只是退回到 base 环境。
(5)删除虚拟环境(注意:该语句要在 base 环境中执行): conda remove -n pytest --all
以上命令行语句都是在 Anaconda (Powershell) Prompt 中使用。你可能要问,在 cmd 或 Windows Powershell 中可以用吗?
在 cmd 或 Windows Powershell 中,首先你就会发现命令行开头没有 (base) 或 (虚拟环境名) 标识,这样就无法知道当前是在哪个环境中。可以使用 conda env list
和 conda list
,但是无法使用 conda activate ENVNAME
进入虚拟环境。帮助信息显示,可用的 conda 命令为:(choose from 'create', 'export', 'list', 'remove', 'update', 'config')。例如,conda create -n ENVNAME
有效。这样看来,用 cmd 或 Windows Powershell 时只能基于 base 环境?
2022-06-26 更新:cmd 界面可以进入虚拟环境。在 cmd 中输入 activate
,或是在 Git Bash 的命令行界面输入 source activate
,(base) 标识就出现了,可以像 Anaconda Prompt 中一样使用,进入不同的虚拟环境。但是,试了一下,在 Windows Powershell 界面中输入 activate
,不会出现 (base) 标识,无法进入虚拟环境,不知道是什么原因,欢迎指教。
在 conda 网站-管理虚拟环境页面 介绍到,conda activate
适用于 conda 4.6 及之后的版本,对于 conda 4.6 之前的版本, Windows 中使用 activate
或 deactivate
,Linux 和 MaxOS 中使用 source activate
或 source deactivate
。
问题:重装 Anaconda 后,原来的虚拟环境能不能用?
可以。不过我没试过,看到这篇文章介绍:重装前保存好 envs 文件夹,位置:anaconda安装文件夹 > envs 。重新安装 Anaconda 后,从旧的 envs 文件夹复制到新的 anaconda安装文件夹 > envs 中。
3.2 配置虚拟环境
1. 新建虚拟环境时,所需的包一起安装
前面介绍的命令行语句 conda create -n ENVNAME
只能建立一个空的虚拟环境。实际中,经常使用如下语句,在新建虚拟环境的同时,把所需的包一起安装:
conda create -n ENVNAME python=3.x pkg1 pkg2=version
我们对照例子来看看具体怎么使用吧。
例子1: 现在 Anaconda 中的 Python 版本是 3.9.7,我要建一个 Python 3.7 版本(更低版本)或 Python 3.10 版本(更高版本)的虚拟环境,都可以。示例如下:
conda create -n pytest1 python=3.7
conda create -n pytest2 python=3.10
进入虚拟环境后,conda list
可以看到系统安装了一些基础包,如 Python, pip 等。
例子2: 我要安装 JupyterLab(Jupyter Notebook的升级版),pandas 和 seaborn。其中,pandas 指定版本为 1.2.3 ,seaborn 指定版本为 0.8.1。示例如下:
conda create -n pytest3 jupyterlab pandas=1.2.3 seaborn=0.8.1
进入虚拟环境 pytest3 之后,输入 conda list
可以看到安装包和对应版本号,pandas 和 seaborn 版本号均为指定版本号。
疑问1:在虚拟环境 pytest3 中打开 JupyterLab ,使用的库版本是基于 pytest3 吗?还是基于 base 环境呢?
试一下就知道了。进入虚拟环境 pytest3,输入 jupyter lab
,打开 JupyterLab 界面。JupyterLab 和 Jupyter Notebook 使用方法相似。新建一个 notebook,输入:
import pandas as pd
import seaborn as sns
print(pd.__version__)
print(sns.__version__)
输出结果为:
1.2.3
0.8.1
base 环境中的 pandas 和 seaborn 版本分别为 1.3.4 和 0.11.2,和虚拟环境 pytest3 的安装版本不同。可见,在虚拟环境中进入到 JupyterLab,notebook 就是在该虚拟环境中运行。
疑问2:新建 pytest3 时,不需要安装 python 吗?
我也试了使用以下语句,加上 Python 的安装:
conda create -n pytest4 python jupyterlab pandas=1.2.3 seaborn=0.8.1
效果是一样的。
我分析,如果要安装的 package 是基于 Python 的,例如 pandas, NumPy 等,由于 Python 是依赖包,因此会一起安装 Python,conda create
语句中不写 python 也可以。此外,不设置 Python 版本的话,conda 会根据要安装的 packages 确定合适的 Python 版本,不一定是最新版本,而是可以让库兼容运行的 Python 版本。比如这里 pytest3/pytest4 安装的是 Python 3.7.13,不是 Anaconda 中的 Python 3.9.7。这是我在实验中得到的结论,如果有误,请您指正,谢谢!
2. 在虚拟环境中安装包(...安装报错需要关掉网络代理软件...)
前面已经介绍,使用 conda activate ENVNAME
进入某个虚拟环境之后,可以用 conda list
查看环境中已安装的包 ( packages )。
新建了一个虚拟环境之后,有时我们需要在其中安装和管理 package,操作方法和 base 环境是相同的。以下是一些常用的 conda 命令,你只要把 pkg_name 换成对应的需要安装的 package,如:pandas, seaborn, numpy, 等等。输入命令之前,首先要进入到需要操作的虚拟环境之中:
- 查看某个 package 是否在当前环境中:
conda list pkg_name
- 查看某个 package 有哪些可安装的版本:
conda search pkg_name
- 安装某个 package:
conda install pkg_name
指定版本安装:conda install pkg_name==version
或conda install pkg_name=version
(我测试了一下,这两条语句效果一样,如果有误,请指正,谢谢!) - 更新某个 package:
conda update pkg_name
更新所有可升级的 packages:conda update --all
- 删除某个 package:
conda remove pkg_name
还有一个更新 conda 的命令行语句:conda update conda
,可以升级 conda 版本。例如,我安装的 Anaconda 中,使用该命令语句, conda 从 4.10.3 升级到了 4.12.0。我在使用中发现,这条 conda 命令只能用在 base 环境中。
升级了 conda 之后,可以接着升级 Anaconda:conda update anaconda
,会升级 base 环境所有可升级的库。例如,我安装的 Anaconda 中, base 环境的 JupyterLab 从 3.2.1 升级到了 3.3.2,NumPy 从 1.20.3 升级到了 1.21.5,等等。如果要升级虚拟环境中可升级的库,可以在虚拟环境中使用上面介绍的 conda update --all
。
3. 什么时候用 pip ?
刚学习 Python 时,我们或多或少都用过 pip(另一种 package 管理工具)安装库,那么,Anaconda 中可以用 pip 吗?
可以,但是 如果 conda 有的 package,推荐用 conda 安装。conda 没有的,再用 pip 安装。
有的包 conda 中没有,只能通过 pip 安装,下面例子中的安装包 see 就是这样。
(1)首先新建一个名为 ‘testpip’ 的虚拟环境 :
conda create -n testpip
(2)进入到虚拟环境 testpip 中:
conda activate testpip
输入conda list
可以看到,此时虚拟环境 testpip 为空,没有安装包。
(3)尝试用 conda 安装 see:
conda install see
提示:未安装成功,显示: ‘PackagesNotFoundError’,conda 中没有找到安装包,如下图所示:
conda install未安装成功-结果页面
(4)使用 pip 安装 see:
pip install see
显示是安装成功了,可是输入 conda list
,发现 package 列表还是为空。这是怎么回事呢?
原因:还没安装 pip,需要先安装 pip:
conda install pip
再安装 see:
pip install see
下图所示为安装结果的一部分:
使用pip安装包
可以看到,pip 配备了清华源。不知道是否因为 conda 设置好了清华源, pip 不用再设置。
再运行 conda list
,结果如下图所示,可以看到安装包 see 是 pip 安装。
conda list 查看安装包 see
但是我发现,在这之前 base 环境没有安装 see。使用 pip 安装 see 之后,base 环境中也安装了 see,其它虚拟环境则没有。我卸载了 base 环境的 see,再尝试用 python -m pip install see
在虚拟环境中安装 see,这一次对 base 环境没有影响。因此,推荐用 pip 时在前面加上 python -m
,这样会明确 pip 关联到当前 Python Interpreter(Python 解释器)。当系统有多个 Python 版本时,python -m
可以避免出现不知道实际安装到了哪个 Python 中,升级 package 后打开发现还是旧版本的问题。
3.3 导出或导入虚拟环境(yml, txt 文件)
不知你有没有遇到过这种情况,比如机器学习的教程,作者老师在 github 分享了代码,下载之后,运行代码时,发现一些库自己的系统没安装,一些库版本不对,总之就是要调试半天,呜呜呜,我以前就弄过。学习了导入导出虚拟环境之后,我特意回顾了一下教程代码,发现大多都提供了 environment.yml 或 requirements.txt 之类的环境配置文件,要是早点知道这部分内容就省了好多事。如果你要分享代码给别人,也可以用这个方法导出虚拟环境,一同发送,这样对方导入后也可以在相同的环境中运行,能避免库版本不兼容的问题。
1.使用 conda 导出虚拟环境至 yml
以下语句中,ENVNAME 为虚拟环境名。envname为 yml 文件名,可以与 ENVNAME 不同,比如,很多地方用 environment 作为 envname。
方法一:在虚拟环境中,运行:conda env export > envname.yml
方法二:或者在 base 环境中,运行:conda env export -n ENVNAME > envname.yml
注意:(1)导出的 envname.yml 文件存放在 Anaconda (Powershell) Prompt 当前运行的文件夹中。如果导出的 yml 命名为 environment.yml,而当前目录已经有 environment.yml,此时会重写文件。(2)虽然是 conda 命令,如果使用了 pip 安装 package,这一 package 的设置也会写入。比如,我在一个虚拟环境中先用 conda 安装了 NumPy,然后又用 pip 安装了 see,导出为 yml 文件。发现在 yml 文件 “dependencies”( 也就是 packages 列表)中,有一项是用 pip 安装的 packages ,如下图所示:
yml文件
问题:在安装一个包时,往往会安装很多依赖包,跨平台使用时,不一定这些依赖包可以通用。
解决方法:导出 精简版,即只导出这个包,不导出其依赖包。做法:在 conda env export
后加上 --from-history
:conda env export --from-history -n ENVNAME > envname.yml
两者区别:
(1)conda env export
:导出安装包和依赖包、及版本号。比如说,我安装了 SciPy,导出环境时,不只导出 SciPy 及其版本号,还导出它的依赖包和版本号,如下图所示:
conda env export导出yml文件
(2)conda env export --from-history
:只导出安装包。这里我测试了两种情况:
情况一:如果安装时没设定版本号,导出文件只有 package(安装包) 名字,如下图所示:
精简版-导出的yml-无版本号
情况二:如果安装时设定了版本号,例如:配置虚拟环境 test2 时设置 package 版本号:conda create -n test2 scipy=1.3.2
,以及在虚拟环境 test2 中安装 package 时设置版本号: conda install pandas=1.2.3
,版本号都会和 package 名一起导出。如下图所示:
精简版-导出的yml-有版本号
2. 使用 conda 从 yml 导入为虚拟环境
以下语句中,envname 为 yml 文件名。在 base 环境运行:
方法一:导入 yml 生成虚拟环境:conda env create --file envname.yml
方法二(简易):或者从当前目录中的 environment.yml 生成:conda env create
注意:这里是 conda env create
,不是 conda create
。
你可能会想,怎么没有输入虚拟环境名 ENVNAME 呢?
如果你打开 envname.yml 文件,会发现第一行就是 name: ENVNAME,这就标识了虚拟环境名称 ( ENVNAME ) ,是导出时 conda 写入的。因此,导入 envname.yml 后,会自动生成一个名称为 ENVNAME 的虚拟环境。此外,如果你在同一台机器上导出又导入后,会显示 ENVNAME 已存在。
3. 导出或导入至 txt 文件
(1)使用 pip 导出/导入至 txt:
用 pip 导出:(可导出 package 准确版本号)
python -m pip freeze > requirements.txt
注意:pip 导出只适用于该环境中的 packages 都是用 pip 安装的情况。 如果其中有用 conda 安装的 package,可以导出,但是之后要从这个 requirements.txt 导入虚拟环境,就会报错,无法安装。
用 pip 导入:
注意:该虚拟环境要有 pip。没有的话,先安装 pip: conda install pip
,然后:
python -m pip install -r requirements.txt
(2)使用 conda 导出/导入至 txt:
用 conda 导出:conda list --explicit > pkgs.txt
注意:conda 导出到 txt文件的是 用 conda 安装的 packages 对应的下载链接,而用 pip 安装的 packges 不会导出。
用 conda 导入:(在 base 环境中运行)
conda create -n NEWENV --file pkgs.txt
可以看到,这个语句就是在 conda create -n NEWENV
的基础上加上了 packages 的安装配置,也就是用 conda 新建虚拟环境,同时通过 pkgs.txt 的链接,下载安装其中的 packages。
看到这里你可能要问,用 pip 或 conda 导出虚拟环境到 txt 文件,都分别只适用于只有 pip 安装包或只有 conda 安装包的情形。如果环境中既有 conda 安装、又有 pip 安装的 packages,应该怎么办呢?
方法就是导出为 yml 文件。前面介绍使用 conda 导出虚拟环境到 yml 文件时,举了一个例子:导出安装有NumPy(conda 安装)和 see(pip 安装)的虚拟环境至 yml 文件。yml 文件中会包含 NumPy 和 see 的配置,可以从该 yml 文件导入生成名为 ENVNAME 的虚拟环境。
学习了这些之后,你可以试着自己安装虚拟环境,然后导出;或者找一些教程配套代码,试着导入提供的environment.yml 或 requirements.txt ,来配置代码运行环境。快动手试试吧!
by@宁萌时光
不同版本软件使用
在 Anaconda Navigator中选择不同环境,可下载对应Python版本软件使用