Conda Guide

virtualenv, pyenv, Conda 等环境、包管理器的使用教程。本文系统为干净的 ubuntu 20.04。

Conda 参考资料
https://docs.conda.io/en/latest/

1. Conda 简介与最佳实践

Conda 能下载任何语言(最初是python)的包及其依赖。能灵活切换不同版本的python,隔离环境。能保存环境到配置文件,换个主机重建该环境。Conda 结合了pip与虚拟环境 virtualenv 等技术。默认设置,能安很多 anaconda 的包。

Anaconda 是一个用于科学计算的 Python 发行版,支持主流操作系统, 包含了众多流行的科学计算、数据分析的 Py 包。

最佳实践

Conda的缺点:conda很臃肿,会占用很多硬盘(3.4G)。使用conda会出错,带来新的问题。conda和pip混用可能会产生冲突(conda包可能滞后,导致和pip等源头版本不同步)。Anaconda 是一家商业公司,要注意合规性。优先不选用美国技术,避免美国长臂管辖的风险。Miniconda 是Anaconda的子集,仅包含基本的Python运行环境与conda。

系统自身的python最好不要动,免得影响其稳定性。最理想的是用conda创建py2/py3等环境,然后用conda下的pip安装py包,配置好国内的源,速度杠杠的。用conda安装包经常遇到莫名其妙的报错,且环境的复杂性越来越高。

版本管理和环境隔离最主流的pyenv和virturalenv。pyenv是个多版本管理工具,virtualenv可以创建不同的虚拟环境。可以用pyenv安装需要的版本的python,再在virtualenv中指定python版本。

python包本身包含了 .py, .so 及混合三大类,都支持import后直接使用。使用pip安装遇到crash,要根据提示使用apt,yum安装依赖。如果懒省事,硬盘够多,只需要 conda install 就够了,这也是其核心卖点。conda 当然是可替代的。

用户踩过的坑:
- 我忘记了 scipy 是 conda 装的,用 pip 升级了一下 scipy,整个世界都崩溃了。
- 但是如果涉及到深度学习以外的python环境,比如cpu模拟器 gem5,以及verilog验证框架cocotb等,我还是强烈建议使用pyenv,用anaconda踩了无数的坑。

常用命令

$ conda clean -a #清理缓存

查看环境(当前环境用*表示)conda info -envs 或conda env list
激活环境 conda activate env_name
停用环境 conda deactivate env_name
删除环境 conda remove -n env_name --all

例
$ conda create -n py27 python=2.7
$ conda activate py27
$ pip install torch==0.4
执行完脚本退出
$ conda deactivate 

2. 安装 conda

# https://docs.conda.io/projects/conda/en/latest/user-guide/getting-started.html
# 完整版 https://docs.anaconda.com/anaconda/install/
	https://mirror.tuna.tsinghua.edu.cn/help/anaconda/
# 精简版 https://docs.conda.io/projects/continuumio-conda/en/latest/user-guide/install/macos.html
	https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/

2.1. Anaconda

1. 下载:
$ wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2021.05-Linux-x86_64.sh
或多线程下载: axel -n 30 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2021.05-Linux-x86_64.sh 

2. 安装 
(1) 先备份一下配置文件 
$ cp ~/.bashrc ~/.bashrc-backup

ubuntu20.04 自带python版本
$ which python3
/usr/bin/python3
$ python3 -V
Python 3.8.10


(2) 创建安装目录。最好在另外的盘上,避免根目录过于臃肿
$ mkdir -p /home/wangjl/data/software/
lrwxrwxrwx 1 wangjl wangjl 12 Sep 17 10:22 /home/wangjl/data -> /data/wangjl

(3) 开始安装
$ bash Anaconda3-2021.05-Linux-x86_64.sh
Welcome to Anaconda3 2021.05

In order to continue the installation process, please review the license
agreement.
Please, press ENTER to continue
>>> 回车看协议
摘录几句:
	All rights reserved under the 3-clause BSD License
Do you accept the license terms? [yes|no] # 接受条款
[no] >>> yes

Anaconda3 will now be installed into this location:
/home/wangjl/anaconda3

  - Press ENTER to confirm the location
  - Press CTRL-C to abort the installation
  - Or specify a different location below

[/home/wangjl/anaconda3] >>>/home/wangjl/data/software/anaconda3 #制定一个路径下某个不存在的文件夹
PREFIX=/home/wangjl/data/software/anaconda3
Unpacking payload ...
... 几分钟安装时间 12:07->12:14

installation finished.
Do you wish the installer to initialize Anaconda3
by running conda init? [yes|no]
[no] >>> yes 是否要初始化?

modified      /home/wangjl/.bashrc
==> For changes to take effect, close and re-open your current shell.

If you'd prefer that conda's base environment not be activated on startup, 
   set the auto_activate_base parameter to false: 
conda config --set auto_activate_base false  #这一句话要不要执行呢?
Thank you for installing Anaconda3!
结束。

检查版本信息

(4) 检查版本号和位置
退出当前shell,重新登录linux。

路径已经被修改了,最前面加上了 conda。
$ echo $PATH
/home/wangjl/data/software/anaconda3/bin:/home/wangjl/data/software/anaconda3/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

发现命令行前面多了个(base)字样。
(base) wangjl@wangjl-VB:~$ conda --version
conda 4.10.1
$ which conda
/home/wangjl/data/software/anaconda3/bin/conda

$ pip freeze| grep conda
conda==4.10.1
$ pip list | grep conda #说明 conda 也是一个python包?
conda                              4.10.1
$ pip freeze | wc -l
252


检查py和pip版本号和位置
/data$ python -V
Python 3.8.8
$ which python
/home/wangjl/data/software/anaconda3/bin/python

$ pip -V
pip 21.0.1 from /home/wangjl/data/software/anaconda3/lib/python3.8/site-packages/pip (python 3.8)
$ which pip
/home/wangjl/data/software/anaconda3/bin/pip

检查包安装的位置
$ ls /home/wangjl/data/software/anaconda3/bin | grep jupyter
jupyter
$ pip list | grep jupyter
jupyter                            1.0.0
此外还能查到 conda, flask 等包。

如果想用本机其他版本的py怎么办?
$ whereis python
python: /usr/bin/python3.8 /usr/lib/python3.9 /usr/lib/python3.8 /usr/lib/python2.7 /etc/python3.8 /usr/local/lib/python3.8 /usr/include/python3.8 /data/wangjl/software/anaconda3/bin/python3.8-config /data/wangjl/software/anaconda3/bin/python3.8 /data/wangjl/software/anaconda3/bin/python
试试哪个能用。

检查安装的大小和内容,修改的配置文件。

(5) 安装包占的大小
$ du -sh software/anaconda3/
3.5G	software/anaconda3/

据说安装 miniconda 就会少很多包。只占用400M硬盘。

$ ls software/anaconda3/ #26个文件夹
bin              condabin    doc   etc      info  libexec      licensing  
mkspecs      pkgs     qml        sbin   shell  translations  x86_64-conda_cos6-linux-gnu
compiler_compat  conda-meta  envs  include  lib   LICENSE.txt  man        
phrasebooks  plugins  resources  share  ssl    var

最大的子文件夹是 lib
$ du -s software/anaconda3/* | sort -k1nr
2477884	software/anaconda3/lib
857744	software/anaconda3/pkgs
156784	software/anaconda3/bin
75328	software/anaconda3/include
6844	software/anaconda3/conda-meta
3264	software/anaconda3/mkspecs

$ ls software/anaconda3/lib/ | wc #该文件夹下有1039个包,大多是so文件
   1039    1039   19550

$ conda list | wc
    347    1044   20799
$ conda list | head
# packages in environment at /home/wangjl/data/software/anaconda3:
#
# Name                    Version                   Build  Channel
_ipyw_jlab_nb_ext_conf    0.1.0                    py38_0  
_libgcc_mutex             0.1                        main  
alabaster                 0.7.12             pyhd3eb1b0_0  
anaconda                  2021.05                  py38_0
...
conda                     4.10.1           py38h06a4308_1 
jupyter                   1.0.0                    py38_7 




(6) 检查修改的配置文件
$ vim ~/.bashrc-backup  #117行
$ vim ~/.bashrc #133行

其中118行之后是
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/home/wangjl/data/software/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/home/wangjl/data/software/anaconda3/etc/profile.d/conda.sh" ]; then
        . "/home/wangjl/data/software/anaconda3/etc/profile.d/conda.sh"
    else
        export PATH="/home/wangjl/data/software/anaconda3/bin:$PATH"
    fi  
fi
unset __conda_setup
#  conda initialize 


(7) 尝试启动jupyter
$ jupyter notebook --no-browser --ip=192.168.2.242 --port=8889
浏览器访问:http://192.168.2.242:8889/?token=aa99e15c704bfc695fe6880e2e57d253176eae378146efcc
可以访问并执行python脚本。


(8) 去掉前面的(base)
$ conda config --set auto_activate_base false
再次登录linux,前面的(base) 消失了。但是jupyter也不能访问了。

[推荐] 我是这样配置 conda 的:

优点是cmd前缀没了,看着正常了;缺点是deactive掉base后需要重新su登录一次。

在.bashrc文件末尾加一行
$ vim ~/.bashrc
export PATH=/home/wangjl/data/software/anaconda3/bin:$PATH

$ source ~/.bashrc
$ which python3
/home/wangjl/data/software/anaconda3/bin/python3
$ which pip3
/home/wangjl/data/software/anaconda3/bin/pip3

jupyter又可以用了。
之后使用 pip3 安装包。


$ pip3 search flask
WARNING: Keyring is skipped due to an exception: Failed to unlock the collection!
ERROR: XMLRPC request failed [code: -32500]
RuntimeError: PyPI's XMLRPC API is currently disabled due to unmanageable load 
and will be deprecated in the near future. See https://status.python.org/ for more information.
pip 搜索由于受到攻击,2021年中宣布永久停止搜索,不知道以后会不会恢复。

2.2. Miniconda

1. 下载 
$ wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-py39_4.10.3-Linux-x86_64.sh
64M

2. 安装 
(1) 先备份一下配置文件 
$ cp ~/.bashrc ~/.bashrc-backup

ubuntu20.04 自带python版本
$ which python3
/usr/bin/python3
$ python3 -V
Python 3.8.10

(2) 创建安装目录。最好在另外的盘上,避免根目录过于臃肿
$ mkdir -p /home/wang/data/software/
lrwxrwxrwx 1 wang wang 11 Sep 24 14:42 /home/wang/data -> /data/wang/

(3) 开始安装
$ bash Miniconda3-py39_4.10.3-Linux-x86_64.sh
Welcome to Miniconda3 py39_4.10.3

> Enter, q, yes 接受协议。
> /home/wang/data/software/miniconda3 #指定一个路径下某个不存在的文件夹
Do you wish the installer to initialize Miniconda3
by running conda init? [yes|no]
[no] >>> yes

==> For changes to take effect, close and re-open your current shell.
If you'd prefer that conda's base environment not be activated on startup, 
   set the auto_activate_base parameter to false: 

conda config --set auto_activate_base false
Thank you for installing Miniconda3!
安装结束。





(4) 检查版本号和位置
退出当前shell,重新登录linux。
发现命令行前面多了个(base)字样。

$ su wang
Password: 
(base) wang@wangVM:~/data/download$ 

路径已经被修改了,最前面加上了 conda。
$ echo $PATH
/home/wang/data/software/miniconda3/bin:/home/wang/data/software/miniconda3/condabin:...

$ conda --version
conda 4.10.3
$ which conda
/home/wang/data/software/miniconda3/bin/conda

$ python -V
Python 3.9.5
$ which python
/home/wang/data/software/miniconda3/bin/python

$ pip -V
pip 21.1.3 from /home/wang/data/software/miniconda3/lib/python3.9/site-packages/pip (python 3.9)
$ which pip
/home/wang/data/software/miniconda3/bin/pip


(5) 安装包占的大小
$ du -sh ~/data/software/miniconda3/
311M	/home/wang/data/software/miniconda3/

$ ls software/miniconda3/ #14个文件夹
bin  compiler_compat  condabin  conda-meta  envs  etc  include  lib  LICENSE.txt  pkgs  share  shell  ssl  x86_64-conda_cos6-linux-gnu  x86_64-conda-linux-gnu

最大的子文件夹是 lib
$ du -s software/miniconda3/* | sort -k1nr
162252	software/miniconda3/lib
126928	software/miniconda3/pkgs
20812	software/miniconda3/bin
5756	software/miniconda3/include
1068	software/miniconda3/share

$ ls software/miniconda3/lib/ | wc #该文件夹下有129个包,大多是so文件

$ conda list | wc
     41     126    2419
$ conda list 
sqlite                    3.36.0               hc218d9a_0 
yaml                      0.2.5                h7b6447c_0


(6) 检查修改的配置文件
$ vim ~/.bashrc-backup  #117行
$ vim ~/.bashrc #133行

其中118行之后是
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/home/wang/data/software/miniconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/home/wang/data/software/miniconda3/etc/profile.d/conda.sh" ]; then
        . "/home/wang/data/software/miniconda3/etc/profile.d/conda.sh"
    else
        export PATH="/home/wang/data/software/miniconda3/bin:$PATH"
    fi  
fi
unset __conda_setup
#  conda initialize 


(7) 尝试启动jupyter
没有,需要安装。
$ pip install jupyter
$ jupyter notebook --no-browser --ip=192.168.2.156 --port=8889


(8) 去掉前面的(base)
$ conda config --set auto_activate_base false
再次登录linux,前面的(base) 消失了。但是jupyter也不能访问了。

为了保证还是使用新python,在.bashrc文件末尾加一行
$ vim ~/.bashrc
export PATH=/home/wang/data/software/miniconda3/bin:$PATH

$ su wang 

$ which pip
/home/wang/data/software/miniconda3/bin/pip
命令前没有base了,也可启动 jupyter。

3. 用conda切换python环境

命令参考: conda-cheatsheet.pdfconda 全部命令

参数中 --name and -n are the same, and --envs and -e are the same.

1. #查看虚拟环境
$ conda info --envs # 这2个输出一样
$ conda env list 
# conda environments:
#
base                  *  /home/wangjl/data/software/anaconda3


2. 创建虚拟环境
$ conda create -n py3.6test python=3.6 #开始安装依赖包

其他例子:
$ conda create --name snakes39 python=3.9 #参数全称是 --name
$ conda create -n myenv sqlite #创建一个环境,并安装sqlite包

conda create -n py36 python=3.6 anaconda  #Python 3.6 的 Anaconda 环境
conda create -n py27 python=2.7 anaconda  #Python 2.7 的 Anaconda 环境


3. 激活环境
$ source activate py3.6test

在该环境下操作
(py3.6test) wangjl@wangjl-VB:~/data$ python -V
Python 3.6.13 :: Anaconda, Inc.
$ pip -V
pip 21.0.1 from /home/wangjl/data/software/anaconda3/envs/py3.6test/lib/python3.6/site-packages/pip (python 3.6)
$ pip install snakemake
$ snakemake --version
6.8.0

4. 退出该环境
$ conda deactivate

如果退出2次,则base也退出了。再次登录则自己设定的生效,base的python又回来了。


5. 要删除一个已有的环境
$ conda env list 
# conda environments:
#
base                  *  /home/wangjl/data/software/anaconda3
py3.6test                /home/wangjl/data/software/anaconda3/envs/py3.6test

$ conda remove --name py3.6test --all
再查就一个base了。
实例2: 安装一个过时的 numpy 环境
$ pip3 list | grep numpy
numpy                              1.20.1

$ source activate base
$ conda create -n numpy16 numpy=1.16 #同意安装包
$ source activate numpy16
$ echo $PATH
/home/wangjl/data/software/anaconda3/envs/numpy16/bin:/home/wangjl/data/software/anaconda3/condabin:/home/wangjl/data/software/anaconda3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
原来 numpy16/bin 被放到了PATH的最前面。

$ conda deactivate

4. 使用pip的国内镜像

1. 如果网速太慢,可以使用国内的镜像 
$ pip install snakemake -i https://pypi.douban.com/simple/ 

$ pip config set global.index-url https://pypi.douban.com/simple

https://pypi.tuna.tsinghua.edu.cn/simple 清华
https://pypi.douban.com/simple/ 豆瓣
https://mirrors.aliyun.com/pypi/simple/ 阿里



2. 查看某已安装包的信息:版本、位置、依赖等

$ pip3 show jupyter
Name: jupyter
Version: 1.0.0
Summary: Jupyter metapackage. Install all the Jupyter components in one go.
Home-page: http://jupyter.org
Author: Jupyter Development Team
Author-email: jupyter@googlegroups.org
License: BSD
Location: /data/wangjl/software/anaconda3/lib/python3.8/site-packages
Requires: ipykernel, qtconsole, ipywidgets, jupyter-console, nbconvert, notebook
Required-by:

5. 使用 conda 查询和下载包 (channels 管理)

pip只管理python包,非python包可以使用 conda 安装。

优先使用原包的官方推荐安装方式。遇到报错实在解决不了再考虑 conda 。

1. 安装质控软件 fastqc 
$ conda search fastqc
PackagesNotFoundError: The following packages are not available from current channels:
当前渠道搜不到,可以换渠道


2. 换国内渠道
末尾添加 渠道名字
## https://mirror.tuna.tsinghua.edu.cn/help/anaconda/
$ vim ~/.condarc 
channels:
  - defaults
show_channel_urls: true
default_channels:
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2
custom_channels:
  conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud

即可添加 Anaconda Python 免费仓库。
$ conda clean -i #清除索引缓存,保证用的是镜像站提供的索引。
运行 conda create -n myenv numpy 测试一下吧。

$ conda search fastqc #再试还是找不到



3. 试试 添加 bioconda 渠道  
添加源
$ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda
$ conda config --set show_channel_urls yes # 生成 ~/.condarc 文件
$ conda config --show

$ conda clean -i #清除索引缓存

查看修改的部分
$ vim ~/.condarc #发现在 channels 部分添加了一行
channels:
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda #添加的行,感觉多余,和后面的重复。
  - defaults
...

再次搜索,可以了
$ conda search fastqc
Loading channels: done
# Name                       Version           Build  Channel             
fastqc                        0.10.1               0  bioconda            
fastqc                        0.10.1               1  bioconda
...
fastqc                        0.11.9      hdfd78af_1  bioconda 



4. 安装 
(1)为了不污染当前环境,我们新建一个环境。
不用的时候可以整体删除掉该环境。

$ conda create --name test_env
environment location: /home/wangjl/data/software/anaconda3/envs/test_env

$ conda activate test_env

$ conda search fastqc
Loading channels: done
# Name                       Version           Build  Channel             
fastqc                        0.10.1               0  bioconda 
...
fastqc                        0.11.9      hdfd78af_1  bioconda

安装最新版的
$ conda install fastqc=0.11.9
## Package Plan ##
  environment location: /home/wangjl/data/software/anaconda3/envs/test_env
  added / updated specs:
    - fastqc=0.11.9
The following packages will be downloaded:
    package                    |            build
    ----------- ---------------|-----------------
    fastqc-0.11.9              |       hdfd78af_1         9.7 MB  bioconda
    font-ttf-dejavu-sans-mono-2.37|       hd3eb1b0_0         335 KB  defaults
    fontconfig-2.13.1          |       h6c09931_0         250 KB  defaults
    freetype-2.10.4            |       h5ab3b9f_0         596 KB  defaults
    icu-58.2                   |       he6710b0_3        10.5 MB  defaults
    libpng-1.6.37              |       hbc83047_0         278 KB  defaults
    libuuid-1.0.3              |       h1bed415_2          15 KB  defaults
    libxml2-2.9.12             |       h03d6c58_0         1.2 MB  defaults
    openjdk-8.0.152            |       h7b6447c_3        57.4 MB  defaults
    perl-5.26.2                |       h14c3975_0        10.5 MB  defaults
    ------------ -------------- ----------------- ---------------
                                           Total:        90.7 MB
加上依赖总共需要90M硬盘空间。

查看其安装位置:
$ ls -lth /home/wangjl/data/software/anaconda3/envs/test_env/bin  | grep fastqc
lrwxrwxrwx 1 wangjl wangjl   27 Sep 17 16:06 fastqc -> ../opt/fastqc-0.11.9/fastqc
$ du -sh /home/wangjl/data/software/anaconda3/envs/test_env/opt/fastqc-0.11.9/
12M	/home/wangjl/data/software/anaconda3/envs/test_env/opt/fastqc-0.11.9/


(2) 搜索另一个生信软件
$ conda search bwa
Loading channels: done
# Name                       Version           Build  Channel             
bwa                            0.5.9               0  bioconda
...
bwa                           0.7.17      pl5.22.0_2  bioconda


(3)安装多个包
conda install fastqc multiqc




5. conda 包管理
(1)更新特定包
conda update fastqc

更新Python
conda update python

更新conda本身及Anaconda元数据包
conda update conda
conda update anaconda

防止包更新
conda update fastqc --no-pin
在环境的conda-meta目录中,添加一个名为pinned的文件,其中包含您不想更新的软件包列表。


(2) 包删除
删除当前环境中的包
conda remove pkg_name

删除特定环境中的包
conda remove -n env_name pkg_name

删除多个包
conda remove pkg_name1 pkg_name2

确认可以删除的包
conda list


(3) 包列表
当前环境所有包
conda list

特定环境所有包
conda list -n env_name

6. conda 环境管理功能

1. 创建环境
创建特定名字的环境
conda create -n env_name

使用特定版本的Python创建环境
conda create -n env_name python=3.7

使用特定包创建环境
conda create -n env_name pandas

用 environment.yml 配置文件创建环境
$ conda env create -f environment.yml

$ cat environment.yml
name: stats2
channels:
  - javascript
dependencies:
  - python=3.8   # or 2.7
  - bokeh=0.9.2
  - numpy=1.9.*
  - nodejs=0.10.*
  - flask
  - pip:
  - Flask-Testing



2. 导出环境文件environment
导出environment.yml环境文件

(1) 先进入需要导出的环境
$ conda activate env_name

(2) 导出:当前环境,输出为yaml配置文件
$ conda env export > environment2.yml

导入:使用该环境文件,创建一个新环境
$ conda env create  --name env_name3 -f environment2.yml

$ cat  environment2.yml
name: test_env
channels:
  - bioconda
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda
  - defaults
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=4.5=1_gnu
  - fastqc=0.11.9=hdfd78af_1
  - font-ttf-dejavu-sans-mono=2.37=hd3eb1b0_0
  - fontconfig=2.13.1=h6c09931_0
  - freetype=2.10.4=h5ab3b9f_0
  - icu=58.2=he6710b0_3
  - libgcc-ng=9.3.0=h5101ec6_17
  - libgomp=9.3.0=h5101ec6_17
  - libpng=1.6.37=hbc83047_0
  - libstdcxx-ng=9.3.0=hd4cf53a_17
  - libuuid=1.0.3=h1bed415_2
  - libxml2=2.9.12=h03d6c58_0
  - openjdk=8.0.152=h7b6447c_3
  - perl=5.26.2=h14c3975_0
  - xz=5.2.5=h7b6447c_0
  - zlib=1.2.11=h7b6447c_3
prefix: /home/wangjl/data/software/anaconda3/envs/test_env



3. 构建相同的环境
(1) 构建相同的conda环境(不同机器间的环境复制)
激活需要导出配置文件的环境
conda list --explicit > files.txt

在同系统的不同机器执行
conda create --name env_name -f files.txt

(2) 克隆环境(同一台机器的环境复制
conda create --name clone_env_name --clone env_name



4. 渠道管理
添加新渠道到顶部,最高优先级
conda config --add channels new_channel
或者conda config --prepend channels new_channel

添加新渠道到底部,最低优先级
conda config --append channels new_channel

7. virtualenv 创建虚拟py环境

安装和切换多个 python 版本,可在 bashrc 里面设置alias调用不同的版本。或者使用虚拟空间 virtualenv。而 conda 吸收了该特性,缺点就是conda太重、太臃肿了,而 virtualenv 更轻量,更适合于多版本测试、发布。

1. 主环境下已有 conda 安装的py版本
$ python3 --version
Python 3.9.5

$ which python3
/home/wang/data/software/miniconda3/bin/python3

$ pip3 --version
pip 21.1.3 from /home/wang/data/software/miniconda3/lib/python3.9/site-packages/pip (python 3.9)

$ which pip3
/home/wang/data/software/miniconda3/bin/pip3



2. 创建python3的虚拟环境
(1) 安装虚拟环境 
## sudo apt install virtualenv
## sudo apt remove virtualenv

py包建议使用pip管理。
$ pip3 install virtualenv

$ virtualenv -h # 可能要等很久,比如 20s 以上



(2) virtualenv - create virtual Python instances
假定我们要开发一个新的项目,需要一套独立的Python运行环境,可以这么做:
step1:创建目录
$ mkdir myproject
$ cd myproject

step2:创建并进入虚拟环境1
$ virtualenv -p python3 env1 #等待一会
created virtual environment CPython3.9.5.final.0-64 in 503ms
  creator CPython3Posix(dest=/home/wang/myproject/env1, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/wang/.local/share/virtualenv)
    added seed packages: pip==21.2.4, setuptools==58.1.0, wheel==0.37.0
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
$ ls
env1


$ source env1/bin/activate #进入虚拟环境1
(env1) wang@wangVM:~/myproject$ ##注意到命令提示符变了,有个(venv)前缀,表示当前环境是一个名为 env1 的Python环境。

(env1) wang@wangVM:~/myproject$ python3 -V
Python 3.9.5
(env1) wang@wangVM:~/myproject$ which python3
/home/wang/myproject/env1/bin/python3

(env1) wang@wangVM:~/myproject$ pip3 -V
pip 21.2.4 from /home/wang/myproject/env1/lib/python3.9/site-packages/pip (python 3.9)
(env1) wang@wangVM:~/myproject$ which pip3
/home/wang/myproject/env1/bin/pip3

$ pip3 freeze #当前什么包都没有安装,就是个干净的python环境

安装 jinja2 包 
(env1) wang@wangVM:~/myproject$ pip3 install jinja2
Collecting jinja2
  Downloading Jinja2-3.0.2-py3-none-any.whl (133 kB)
     |████████████████████████████████| 133 kB 873 kB/s 
Collecting MarkupSafe>=2.0
  Using cached MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (30 kB)
Installing collected packages: MarkupSafe, jinja2
Successfully installed MarkupSafe-2.0.1 jinja2-3.0.2

再次查看有哪些包
(env1) wang@wangVM:~/myproject$ pip3 freeze
Jinja2==3.0.2
MarkupSafe==2.0.1

在venv1环境下,用pip安装的包都被安装到venv1这个环境下,系统Python环境不受任何影响。也就是说,venv1环境是专门针对myproject这个应用创建的。


step3:退出当前的env2环境 
(env1) wang@wangVM:~/myproject$ deactivate
wang@wangVM:~/myproject$ 


如何删除虚拟环境?
实际上一个虚拟环境就是一个文件夹,你把这个文件夹删了就是了。



此时就回到了正常的环境,现在pip或python均是在系统Python环境下执行。
wang@wangVM:~/myproject$ which python3
/home/wang/data/software/miniconda3/bin/python3

wang@wangVM:~/myproject$ python3 -V
Python 3.9.5

完全可以针对每个应用创建独立的Python运行环境,这样就可以对每个应用的Python环境进行隔离。

virtualenv是如何创建“独立”的Python运行环境的呢?原理很简单,就是把系统Python复制一份到virtualenv的环境,用命令source env1/bin/activate进入一个virtualenv环境时,virtualenv会修改相关环境变量,让命令python和pip均指向当前的virtualenv环境。

小结: virtualenv为应用提供了隔离的Python运行环境,解决了不同应用间多版本的冲突问题。

好处:为项目创建一个干净的开发环境。

8. pyenv - Python版本管理神器

pyenv通过在PATH头部插入 shims 路径来实现对python版本的控制。它工作在用户空间,因而不需要sudo权限,不会影响系统全局Python解释器。

Pyenv 是一个Python 版本的托管; 而Pyenv-virtualenv 他是对python 虚拟环境的一个托管。

pyenv和流行的pipenv、virtualenv的关系? //todo

特性:1. 进行全局的 Python 版本切换 2. 为单个项目提供对应的 Python 版本 (进入文件夹自动激活某版本) 3. 使用环境变量能让你覆盖 Python 版本 4. 能在同一时间在不同版本的 Python 间进行命令搜索

Pyenv的神奇之处在于它实际上重新定义了你的python命令:
$ which python
/home/staff/jmoreira/.pyenv/shims/python
当你试图去运行Python时,它会在当前目录中查找一个 .python-version 文件去决定使用哪个版本的python。如果不存在这个文件,它会自动去寻找用户空间的 ~/.pyenv/version 文件。

# 以下基于 Ubuntu 系统。
使用 pyenv 和 pyenv-virtualenv ,在 linux 下完美隔离 python 各个版本

Simple Python Version Management: pyenv

1. 下载和安装 

参考 https://github.com/pyenv/pyenv

首先把项目克隆下来,放在家目录下的隐藏文件夹中:.pyenv
你也可以安装在其他地方。
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv

推荐固定版本号
$ cd ~/.pyenv 
$ git tag
$ git checkout v2.1.0


2. 然后配置环境变量 (Ubuntu的配置)

# the sed invocation inserts the lines at the start of the file
# after any initial comment lines
$ sed -Ei -e '/^([^#]|$)/ {a \
export PYENV_ROOT="$HOME/.pyenv"
a \
export PATH="$PYENV_ROOT/bin:$PATH"
a \
' -e ':a' -e '$!{n;ba};}' ~/.profile

$ echo 'eval "$(pyenv init --path)"' >>~/.profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc


3. 重新登录 
$ su wang  #不行,报错 Command 'pyenv' not found, did you mean

$ exit
$ ssh xx@IP #重新登录才行
是不是和载入有关? ~/.profile  ~/.bashrc //todo


(2) 验证是否安装成功
$ pyenv -v
pyenv 2.1.0


4. 安装 py build 需要的包 (极其慢,可能需要1个小时。能否跳过?)
$ sudo apt-get update; sudo apt-get install make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev

$ sudo apt autoremove





5. 使用

(1)查看可安装的Python版本
$ pyenv install --list
  2.1.3
  2.7.18
  ...
  3.6.15
  3.10.0

(2) 安装指定版本的 py
其中 -v 可省略: pyenv install 3.8.10

$ pyenv install -v 2.7.13
	
1) https://www.python.org/ftp/python/2.7.8/Python-2.7.8.tar.xz 会报错
安装时报错 ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?
https://stackoverflow.com/questions/52873193/error-the-python-ssl-extension-was-not-compiled-missing-the-openssl-lib-inst/52873194
版本原因。要么重装有些库,要么安装特定版本。

2) 下载很慢,甚至下载失败
可以先从官网下载所需要的版本的源代码到 ~/.pyenv/cache 目录下,再执行安装命令。
https://www.python.org/downloads/source/, 
或换个国内的源 https://mirrorz.org/list/python

wget https://mirror.bjtu.edu.cn/python/2.7.13/Python-2.7.13.tar.xz

$ cd ~/.pyenv/cache/
$ wget https://mirror.bjtu.edu.cn/python/3.6.1/Python-3.6.1.tar.xz
$ pyenv install -v 3.6.1

# 或者使用以下命令安装:
v=3.8.10;wget https://npm.taobao.org/mirrors/python/$v/Python-$v.tar.xz -P ~/.pyenv/cache/;pyenv install $v 
# v代表你要安装的版本

# 在淘宝镜像上下载指定版本的Python, 并使用pyenv install 安装 
v=3.6.3;wget https://npm.taobao.org/mirrors/python/$v/Python-$v.tar.xz -P ~/.pyenv/cache/;pyenv install $v 



(3) 查看pyenv已安装的Python版本,如果装了其他版本那么会显示多个
$ pyenv version #当前版本

$ pyenv versions #所有 pyenv 托管的版本,*表示当前版本
* system (set by /home/wang/.pyenv/version)
  2.7.13
  3.6.1

(4) 指定全局Python版本: pyenv global 版本号
$ pyenv global 3.6.1

查询 
$ pyenv global
3.6.1


如果不生效,请退出再登录
$ exit 
$ ssh xx@IP 

$ python -V
Python 3.6.1
$ which python
/home/wang/.pyenv/shims/python 

$ which pip
/home/wang/.pyenv/shims/pip
$ pip -V
pip 9.0.1 from /home/wang/.pyenv/versions/3.6.1/lib/python3.6/site-packages (python 3.6)


(5) 回到之前的默认python 环境
$ pyenv global system

实际上当你切换版本后, 相应的pip和包仓库都是会自动切换过去的

更多命令,见下文。

pyenv 的虚拟环境 virtualenv 插件

为了对不同的项目进行隔离,使每个项目使用独立的 python 解释器及依赖,需要配置 python 虚拟环境。

使用 pyenv-virtualenv 创建 python 虚拟环境,实质上是在~/.pyenv/versions/3.6.1/ 下创建一个文件夹 evns,存放该虚拟环境 python的解释器;并且在 ~/.pyenv/ 下创建一个软连接,该虚拟环境可以通过 pyenv 进行管理。

6. 推荐安装一个插件 pyenv-virtualenv

(1) 把插件克隆在刚才已经安装完毕的 pyenv 的 plugins 文件夹中
$ git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv
(2) 可选,推荐执行。
$ echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc

(3) Restart your shell to enable pyenv-virtualenv
$ exec "$SHELL"

或
$ source ~/.bashrc


(4) 创建虚拟环境
$ cd ~/myproject/

## pyenv vitualenv版本号 虚拟环境名
$ pyenv virtualenv 2.7.13 my_test_27
$ pyenv virtualenv 3.6.1 my_test_36
$ pyenv virtualenv 3.6.1 my_test_36_2

检查文件结构
$ ls -lth ~/.pyenv/versions
total 8.0K
lrwxrwxrwx 1 wang wang   50 Oct 18 20:57 my_test_36_2 -> /home/wang/.pyenv/versions/3.6.1/envs/my_test_36_2
lrwxrwxrwx 1 wang wang   48 Oct 18 16:08 my_test_36 -> /home/wang/.pyenv/versions/3.6.1/envs/my_test_36
drwxr-xr-x 7 wang wang 4.0K Oct 18 16:08 3.6.1
lrwxrwxrwx 1 wang wang   49 Oct 18 16:08 my_test_27 -> /home/wang/.pyenv/versions/2.7.13/envs/my_test_27
drwxr-xr-x 7 wang wang 4.0K Oct 18 16:08 2.7.13



## 激活虚拟环境,有四种方法
$ pyenv activate my_test_27
$ source activate my_test_27
$ source ~/.pyenv/versions/2.7.13/envs/my_test_27/bin/activate my_test_27
$ pyenv shell my_test_27

查版本号
(my_test_27) wang@wangVM:~/myproject$ python -V
Python 2.7.13
(my_test_27) wang@wangVM:~/myproject$ pip -V
pip 20.3.4 from /home/wang/.pyenv/versions/2.7.13/envs/my_test_27/lib/python2.7/site-packages/pip (python 2.7)

pip --version #它会告诉你 pip 包安装的绝对路径,也是 pyenv 安装目录下的某个文件夹
所谓的虚拟环境,就是把 python 装在 pyenv 的安装目录的某个文件夹中,以供它自己调用。

(my_test_27) wang@wangVM:~/myproject$ which pip
/home/wang/.pyenv/shims/pip



## 退出虚拟环境
$ source deactivate
或者:
$ pyenv deactivate

shell 模式则需要单独的退出命令
$ pyenv shell --unset




(5) 使用 local 命令
$ cd ~/myproject
$ pyenv local my_test_36

该目录下生成一个隐藏文件
-rw-rw-r--  1 wang wang   11 Oct 18 16:29 .python-version
文件内容就一行:my_test_36

这样你只要进入 ~/myproject 目录,就会自动激活该虚拟环境。十分好用!





7. 更新 pyenv
由于我们是 git 克隆的,所以更新非常简单

$ cd ~/.pyenv 或者 cd $(pyenv root)
$ git pull


8. 卸载 pyenv

(1) 查看py版本和位置
$ pyenv global system
$ pyenv versions
* system (set by /home/wang/.pyenv/version)
  2.7.13
  2.7.13/envs/my_test_27
  3.6.1
  3.6.1/envs/my_test_36
  3.6.1/envs/my_test_36_2
  my_test_27
  my_test_36

$ cat ~/.pyenv/version
system

wang@wangVM:~$ python -V
Python 3.9.5
$ which python
/home/wang/.pyenv/shims/python

$ pip -V
pip 21.1.3 from /home/wang/data/software/miniconda3/lib/python3.9/site-packages/pip (python 3.9)
$ which pip
/home/wang/.pyenv/shims/pip


(2) 由于 pyenv 把一切都放在 ~/.pyenv 下了,所以卸载很方便,两个步骤就行了

步骤一: 首先需要删除环境变量
$ vim ~/.profile
删除最前面的2行
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
最后的2行
eval "$(pyenv init --path)"

$ vim ~/.bashrc
末尾的2行
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

第二步: 删除文件夹
$ rm -rf ~/.pyenv 或者 rm -rf $(pyenv root)


(2) 重新登录,查看py版本和位置
$ exit #退出 
$ ssh xx@ip 

$ python -V
Python 3.9.5
$ which python
/home/wang/data/software/miniconda3/bin/python

$ pip -V
pip 21.1.3 from /home/wang/data/software/miniconda3/lib/python3.9/site-packages/pip (python 3.9)
$ which pip
/home/wang/data/software/miniconda3/bin/pip

精简命令

十几个子命令
$ pyenv --help
https://github.com/pyenv/pyenv/blob/master/COMMANDS.md#command-reference

基本命令
pyenv commands 查看pyenv命令 
pyenv install --list 查看可安装的python版本 
pyenv versions #查看已安装版本 
pyenv version #查看当前使用的python版本 
pyenv install -v 版本号 


安装python 
pyenv rehash 刷新python已安装列表 
pyenv uninstall 版本号 删除python 
pyenv global 版本号 设置当前全局python版本 
pyenv local 版本号 设置局部python版本 
pyenv local --unset 取消局部python版本设置,或者删除当前目录下的.python-version文件


使用pyenv-virtualenv
pyenv virtualenv 版本号 name  # 创建一个虚拟环境,命名为name 创建好后可通过 pyenv versions 来查看
	$ pyenv vitualenv 3.6.3 my_test_1
pyenv virtualenvs  #查看 python 虚拟环境
pyenv activate name 切换到name虚拟环境中 
pyenv deactivate 退出虚拟环境 
pyenv virtualenv-delete name #删除name环境
或 
pyenv uninstall my-virtual-env #delete virtualenv called my-virtual-env


pyenv global versionNum  // 配置当前用户的系统使用的 python 版本. 可以使用这个命令进行python版本的切换!
pyenv shell versionNum  // 配置当前 shell 的 python 版本,退出 shell 则失效
pyenv local versionNum   // 配置所在项目(目录)的 python 版本

shell 会话设置(只影响当前的会话) 
local 本地设置(只影响所在文件夹)

pyenv global system # 回到之前的默认python 环境
pyenv local system  # 回到之前的默认python 环境


特别注意:如果使用"pyenv global xxx" 以及 "pyenv rehash" 后仍然无法成功切换版本!
	这种情况一般是因为用 pyenv 指定了 local 版本!!
解决办法:取消设置 local 版本,即执行"pyenv local --unset"即可!

conda 与 pyenv 的联合使用: https://github.com/pyenv/pyenv-virtualenv

疑难杂症 / 参考资料

1. 如何升级pip包?
$ python -m pip install --user --upgrade pip==19.1.1

2. 如果win10的pip升级失败,补鞥用了怎么办?
强制重装pip
> curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
> python3 get-pip.py 
> pip -V
conda 官方命令大全 https://docs.conda.io/projects/conda/en/latest/commands.html
Conda 安装使用图文详解(2021版) https://blog.csdn.net/u011262253/article/details/88828229

pyenv: https://www.jianshu.com/p/3e93311fe6cb