Python - Conda - 对比 conda 和 pip
之前已经写过一篇和工具相关的文章:《工具篇:make a sparrow cmake buildsystem》,本文继续这个话题,大家可能都用过conda和pip,但是对于他们的区别和关系,可能大家不一定很清楚,本文来尝试做一些总结。
一、conda
1.1 简介
conda是一个通用的包管理器,意思是什么语言的包都可以用它进行管理,自然也包python,它很像一个跨平台版本的apt或者yum,而且conda是开源的(github链接:https://github.com/conda/conda ),下面是官网的一段介绍:
Conda is a cross-platform, language-agnostic binary package manager. It is the package manager used
by Anaconda installations, but it may be used for other systems as well. Conda makes environments
first-class citizens, making it easy to create independent environments even for C libraries.
Conda is written entirely in Python, and is BSD licensed open source.
1.2 Anaconda和Miniconda
首先,Anaconda是一个2012年成立的具有盈利性质公司的名字(官网地址:https://www.anaconda.com/about-us ),同时Anaconda又是Anaconda公司的一个软件发行版的名字,它包含了PyData生态中的核心软件,conda只是其中之一,除此之外还包括Python本身和数百个第三方开源项目的二进制文件,例如conda、numpy、scipy等。
Anaconda有Free、Pro、Business、Enterprise等版本,意如其名,只有Free版本是免费的,收费版本可以享受更多一些的服务,比如Jupyter notebook services、Long-term Support等,更多信息大家可以从官网上查到。
再说一下Miniconda,它相当于是一个conda环境的安装程序,只包含了conda及其依赖项,这样就可以减少一些不需要的第三方库的安装,所以Miniconda所占用的空间很小。
1.3 conda-forge
默认的conda channel是defaults,但这个channel的package不全,这时候可以选择使用conda-forge,先看一下官网对它的介绍(https://conda-forge.org/docs/user/introduction.html ):
Conda-forge is a community effort that provides conda packages for a wide range of software.
可见conda-forge是一个community,它所提供的package都放在同名的conda-forge这个channel里,建议使用这个channel,并设置严格优先使用conda-forge,因为不同channel的package不一定完全兼容,下面是配置方法:
conda config --add channels conda-forge
conda config --set channel_priority strict
如果在用户根目录没有.condarc这个文件,上面命令会创建这个文件,设置完之后可以通过下面命令查看channel状态和优先级:
conda config --get channels
这条命令可能会得到类似如下的显示:
--add channels 'defaults' # lowest priority
--add channels 'conda-forge' # highest priority
这时~/.condarc的内容如下:
channels:
- conda-forge
- defaults
1.4 常用命令
这里简单列一些相对常用的命令,更多的命令大家可以通过conda --help或者网上的资料来查:
- conda info:显示conda的一些基本信息,后面如果加-e选项可以只显示所有已经创建的环境
- conda list:查看所有已经安装的包
- conda config:配置conda,后面加不同的选项可以完成不同的配置功能,上一节配置channel时用到了这个命令
- conda create:用于创建环境,例如conda create -n env_name package_name
- conda remove:用于删除环境,例如conda remove --name env_name –all
- conda install:在当前环境中安装包,例如conda install pkg
- conda remove:删除当前环境中的包,例如conda remove pkg
二、pip
2.1 简介
pip同conda一样,也是一个包管理器,但它只能管理python包,并且它是python官方认可的包管理器,其中pip的含义是Pip Installs Packages,最常用于安装在PyPI(Python Package Index https://pypi.python.org/pypi )上发布的包,在通过conda list命令查看当前环境下已安装的package时,通过pip安装的package在Channel那一列会显示pypi
2.2 sdist和bdist
pip install的时候,会有可能下载到两种package,即sdist和bist,其中:
- sdist是Source Distribution的缩写,这种package发行的是源码,必须要经过编译才能使用起来
- bdist是Built Distribution的缩写,是指源码被编译好了的package,wheel(.whl)文件就是这种package
再着重说下wheel package,这种package本质上是一个zip文件,是已编译发行版的一种格式,需要注意的是,尽管它是已经编译好的,包里面一般不包含.pyc或是python字节码,一个wheel包的文件名由以下这些部分组成:
{dist}-{version}(-{build})?-{python}-{abi}-{platform}.whl
wheel package有很多好处,它安装快,一般sdist体积小很多,不需要编译器,pip自动为用户生成.pyc文件,免除了setup.py的执行,setup.py是python的disutils、setuptools编译机制所需要的文件,需要执行很多编译和安装工作,如果没有wheel的存在,package的安装维护都会麻烦很多,wheel package有下面三类:
- universal wheel:在package的名字中带有py2.py3-none-any.whl,对python版本、操作系统等均没有要求,兼容性最好
- pure python wheel:在package的名字中带有py3-none-any.whl或py2-none-any.whl,和第一种wheel相比,仅仅在python的版本上有所要求
- platform wheel:对python版本和操作系统等都会有要求,创建这种类型的wheel一般意味着内部使用了一些例如由C++等静态语言编写的代码
wheel这部分的资料主要参考文章最后Reference中的8和9,更多细节大家可以点开这两篇文章看一下。
2.3 常用命令
下面简单列一些相对常用的命令,更多的命令大家可以通过pip --help或者网上的资料来查:
- pip list:列出已安装的包
- pip show:查看指定包的详细信息
- pip freeze:可以查看用pip安装的软件有哪些,以requirements文件的格式显示
- pip install xxx:xxx就是已经安装的软件名字,再重新安装的时候,就会显示安装路径在哪
三、conda install和pip install
这两个命令的相关细节之前在知乎的一个回答里写过(https://www.zhihu.com/question/395145313/answer/2449421755 ),这里重新总结到这里:
- conda install xxx:这种方式安装的库都会放在anaconda3/pkgs目录下,这样的好处就是,当在某个环境下已经下载好了某个库,再在另一个环境中还需要这个库时,就可以直接从pkgs目录下将该库复制至新环境而不用重复下载。
- pip install xxx:分两种情况,一种情况就是当前conda环境的python是conda安装的,和系统的不一样,那么xxx会被安装到anaconda3/envs/current_env/lib/python3.x/site-packages文件夹中,如果当前conda环境用的是系统的python,那么xxx会通常会被安装到~/.local/lib/python3.x/site-packages文件夹中
这里引出一个问题:conda和pip安装同一个xxx库情况下,conda环境下python代码中import xxx时,谁安装的xxx优先级较高会被import,这个问题通过下面这条命令可以解决:
python -m site
在我的机器上,会有类似下面输出:
(py3.6) [~/anaconda3/pkgs @ s64]$ python -m site
sys.path = [
'~/anaconda3/pkgs',
'~/anaconda3/envs/py3.6/lib/python36.zip',
'~/anaconda3/envs/py3.6/lib/python3.6',
'~/anaconda3/envs/py3.6/lib/python3.6/lib-dynload',
'~/anaconda3/envs/py3.6/lib/python3.6/site-packages',
]
USER_BASE: '~/.local' (exists)
USER_SITE: '~/.local/lib/python3.6/site-packages' (doesn't exist)
ENABLE_USER_SITE: True
这里的USER_BASE 和USER_SITE其实就是用户自定义的启用Python脚本和依赖安装包的基础路径,从上面的输出可以看到,import xxx时,先找的是anaconda3/pkgs目录,所以conda安装的包会被import进来
四、conda uninstall和pip uninstall
pip是在特定的环境中进行库的安装,所以卸载库也是一样的道理,通过pip uninstall xxx就可以将该环境下Lib\site-packages中对应的库进行卸载了。
如果通过conda uninstall xxx删除当前环境下某个库时,删除的只是当前环境下site-packages目录中该库的内容,它的效果和通过pip uninstall xxx是一样的。如果再到另一个环境中通过conda install xxx下载这个库,则还是通过将pkgs目录下的库复制到当前环境。若要清空这个pkgs下的已下载库,可以通过命令conda clean -h进行实现。
参考文献
https://zhuanlan.zhihu.com/p/508506160