Anaconda、Miniconda、Conda、pip的相互关系
朱筱0821
0.7442019.08.28 14:11:04字数 5,619阅读 1,513
Anaconda、Miniconda、Conda、pip的相互关系。如果你想要跳过这篇文章,并得到讨论的要点,你可以阅读每个标题以及下面的摘要。
认为#1:Conda是一个发行版,不是一个软件包管理器
现实:Conda是一个包管理器;Anaconda是一个发行包。虽然Conda与Anaconda一起包装,但两者是具有不同目标的不同实体。
软件发布包是预先构建和预配置的包的集合,其可以在系统上安装和使用。包管理器是自动化安装,更新和删除包的过程的工具。 Conda,其“conda install”,“conda update”和“conda remove”子命令,完全属于第二个定义:它是一个包管理器。
也许这里的混乱来自于Conda紧密耦合到两个软件分发:Anaconda和Miniconda的事实。 Anaconda软件在PyData生态系统中的完整分布,包括Python本身以及几百个第三方开源项目的二进制文件。 Miniconda本质上是一个conda环境的安装程序,只包含Conda及其依赖项,以便您可以从头开始安装所需的。
但不要弄错误:Conda与Anaconda / Miniconda不同,Python本身(如果你愿意)可以自行安装。
认为#2:Conda是一个Python包管理器
现实:Conda是一种通用包管理系统,旨在构建和管理任何语言的任何类型的软件。因此,它也适用于Python包。
因为conda来自于Python(更具体地说是PyData)社区,许多人错误地认为它基本上是一个Python包管理器。情况并非如此:conda旨在管理任何软件堆栈中的包和依赖关系。在这个意义上,它不像pip,更像是apt或yum等跨平台版本。
如果你使用conda,你已经可以利用许多非Python包;以下命令将列出您环境中的那些:
$ conda search –canonical | grep -v ‘py\d\d’
在我的系统上,有350个结果:这些是我的Conda / Python环境中的包,这些包基本上是由Python-only工具(如pip和virtualenv)无法管理的。
认为#3:Conda和pip是直接竞争对手
现实:Conda和pip服务于不同的目的,并且只在一小部分任务中直接竞争:即在孤立的环境中安装Python包。
Pip代表Pip Installs Packages,是Python的官方认可的包管理器,最常用于安装在Python包索引(PyPI)上发布的包。 pip和PyPI都由Python包装管理局(PyPA)管理和支持。
简而言之,pip是Python包的通用管理器; conda是一个与语言无关的跨平台环境管理器。对于用户,最显著的区别可能是这样的:pip在任何环境中安装python包; conda安装在conda环境中的任何包装。如果你正在做的是在孤立的环境中安装Python包,conda和pip + virtualenv大多是可互换的,模数依赖处理和包可用性的一些差异。通过隔离环境(conda-env或virtualenv),您可以在其中安装软件包,而无需修改您的系统Python安装。
即使放弃认为#2,如果我们专注于只是安装Python包,conda和pip服务不同的受众和不同的目的。 如果你想在现有的系统Python安装中管理Python包,conda不能帮助你:通过设计,它只能在conda环境中安装包。 如果你想说,使用依赖于外部依赖的许多Python包(NumPy,SciPy和Matplotlib是常见的例子),同时以一种有意义的方式跟踪这些依赖,pip不能帮助你:它 管理Python包和只有Python包。
Conda和pip不是竞争对手,而是侧重于不同用户组和使用模式的工具。
认为#4:在第一个地方创造conda是不负责任和分裂
现实:Conda的创作者将Python的标准包装推向了极限十多年,并且只有在明确了它是唯一合理的前进道路时才创造了第二个工具。
根据Python的哲学,在Python做任何事情“应该有一个,最好只有一个明显的方式来做”。那么为什么conda的创建者会通过引入一种新的方式来安装Python包呢?为什么他们没有贡献回Python社区并改进pip来克服它的缺陷?
事实证明,这正是他们所做的。在2012年之前,PyData / SciPy生态系统的开发人员很大程度上在Python社区开发的包管理解决方案的约束下工作。早在2001年,NumPy项目就试图使它处理NumPy分布的复杂要求。他们将大部分的NETLIB绑定到一个单一的Python包(你可能知道这是SciPy),实际上创建一个分发为python包,以规避Python的分发工具不能用任何有意义的方式管理这些额外的Python依赖。为了阅读一些关于这些痛点的细节以及如何导致Conda,我建议Travis Oliphant的2013年博客文章。
但是为什么Conda的创作者不和Python包装人员谈谈,一起找出这些挑战呢?事实证明,他们谈了。
Conda的创始来自Guido van Rossum先生在2012年首届PyData聚会上发表演讲;在一个关于包装困难的问题上,他告诉我们,当谈到包装,“真的听起来像你的需求是相当大的Python社区,你只是更好地建立自己的”的讨论)。即使在遵循这个来自BDFL的建议的情况下,PyData社区继续与核心Python开发人员的对话和协作的主题:另一个公开的例子是CPython核心开发人员Nick Coghlan邀请在SciPy 2014主题演讲(见视频here )。他做了一个很好的演讲,在软件分发的“未解决问题”的背景下具体讨论了pip和conda,并提到了具有适合特定用户需求的多种分发方式的价值。
Conda不是分裂的,Nick和其他人在Python包装管理局正式认可conda作为Python代码的许多重要的重新分发器之一,并且正在努力更好地使这些工具与Python包索引无缝地工作。
认为#5:conda不能使用virtualenv,所以它对我的工作流没有用
现实:你实际上可以在一个virtualenv中安装(一些)conda包,但更好的是使用Conda自己的环境管理器:它与pip完全兼容,并且比virtualenv有几个优点。
virtualenv / venv是允许用户创建与pip一起使用的隔离的Python环境的实用程序。 Conda有自己的内置环境管理器,可以与conda和pip无缝工作,并且事实上比virtualenv / venv有几个优点:
conda环境集成了不同Python版本的管理,包括Python本身的安装和更新。 Virtualenvs必须在现有的,外部管理的Python可执行文件上创建。
conda环境可以跟踪非python依赖;例如无缝管理依赖性和基本工具(如LAPACK或OpenSSL)的并行版本
而不是构建在符号链接上的环境 - 这破坏了virtualenv的隔离,并且对于非Python依赖关系有时可能是脆弱的 - conda-envs是单个可执行路径中的真正隔离环境。
虽然virtualenvs与conda软件包不兼容,但conda环境与pip软件包完全兼容。第一个conda安装pip,然后你可以pip安装任何可用的包在那个环境中。您甚至可以在conda环境文件中显式地列出pip包,这意味着完整的软件堆栈可以从单个环境元数据文件完全重现。
也就是说,如果你想在你的virtualenv中使用conda,它是可能的:
$ virtualenv test_conda
$ source test conda/bin/activate
$ pip install conda
$ conda install numpy
这将在您的virtualenv中安装conda的MKL启用的NumPy包。 我不会推荐这个:我找不到这个功能的文档,并且结果似乎相当脆弱 - 例如,试图conda更新python内的virtualenv失败在一个非常不起眼和不可恢复的方式,看起来与 符合连接virtualenv的架构。 这似乎不是conda和virtualenv之间的一些根本不兼容,而是与构建过程中的一些细微不一致有关,因此是潜在可固定的(例如,参见conda Issue 1367和anaconda Issue 498)。
如果你想避免这些困难,一个更好的想法是pip安装conda,然后创建一个新的conda环境中安装conda包。 对于习惯于使用pip / virtualenv / venv命令语法的人来说,conda文档包括conda和pip / virtualenv命令之间的转换表。
认为#6:现在pip使用wheels,conda不再需要
现实:wheels只是提出conda发展的许多挑战之一,而wheels有弱点,Conda的二进制文件解决。
驱动Conda创建的一个困难是,pip可以只分发源代码,而不是预编译的二进制分发,这对于构建诸如NumPy和SciPy的扩展重模块的用户来说尤其具有挑战性。 Conda以自己的方式解决了这个问题后,pip本身增加了对轮子的支持,这是一个二进制格式,旨在解决pip中的这个难题。有了这个问题在共同的工具,解决Conda早期采纳者现在应该回到pip?
不必要。跨平台二进制文件的分发只是conda中解决的许多问题之一。编译的二进制文件聚焦了conda的另一个重要部分:有意义地跟踪非Python依赖关系的能力。因为pip的依赖关系跟踪只限于Python包,所以在轮子中这样做的主要方法是将发布的依赖包版本与Python包二进制包捆绑在一起,这使得更新这样的依赖很痛苦(最近OpenSSL的安全更新)。此外,conda包括一个真正的依赖解析器,一个pip目前缺乏的组件。
对于科学用户,conda还允许将构建链接到优化的线性代数库,Continuum使用其自由提供的MKL启用的NumPy / SciPy。 Conda甚至可以分发非Python构建需求,例如gcc,这大大简化了在其分发的预编译二进制代码上构建其他包的过程。如果你试图使用pip的轮子,你最好希望你的系统有编译器和设置兼容那些用来最初构建的问题的车轮。
认为#7:conda不开源;它被绑定到一个营利公司,可以开始收取服务,只要他们想要
现实:conda(包管理器和构建系统)是100%开源,Anaconda(发行版)也几乎在那里。
在开放源代码世界中,有一些对营利性实体的根本不信任,而Anaconda是由Continuum Analytics创建的,而且是大型企业产品的一个免费组件,这使得一些人担心。
让我们抛开一个事实,Continuum是,在我看来,是少数几家公司真正做开放软件正确的方式(一个话题另一个时间)。忽略这一点,事实是,Conda本身 - 包管理器,提供以跨平台方式构建,分发,安装,更新和管理软件的实用程序 - 是100%开源,可在GitHub和BSD许可。即使对于Anaconda(发行版),EULA只是一个标准的BSD许可证,用于创建Anaconda的工具链也是100%开源。总之,当使用Conda时,没有必要担心知识产权问题。
如果Anaconda / Miniconda发行版仍然担心,放心:你不需要安装Anaconda或Miniconda来获得conda,虽然这些是方便的使用途径。正如我们上面所看到的,你可以“pip install conda”通过PyPI安装它,而无需Continuum的网站。
认为#8:但Conda包本身是封闭的,对不对?
现实:虽然conda的默认渠道尚未完全开放,有一个由社区主导的努力(Conda-Forge)使conda包装和分销完全开放。
从历史上看,默认conda通道的软件包构建过程没有尽可能开放,并且获取构建更新的过程主要依赖于在Continuum上知道某人。谣言是,这主要是因为原始的conda包创建过程没有像今天一样明确和精简。
但这正在改变。 Continuum正在努力打开他们的包装食谱,并且我被告知,500多个包装中只有几十个仍然需要移植。这些少数食谱是Anaconda分布中唯一不完全开放的剩余部分。
如果这还不够,那么在2016年初推出的一个新的以社区为主导的项目,而不是Continuum附属项目,名为conda-forge,包含用于为任何软件包创建社区驱动的构建的工具。软件包通过github保持开放状态,二进制文件使用免费CI工具自动构建,如TravisCI for Mac OSX构建,AppVeyor for Windows构建和CircleCI for Linux构建。每个包的所有元数据都位于Github存储库中,并且通过合并Github pull请求(这是conda-forge中包更新的示例)完成包更新。
Conda-forge完全是社区为基础的,由社区主导,虽然conda-forge可能还不够成熟,无法完全替代默认的conda渠道,Continuum的创始人已经公开表示,这是他们会支持的方向。你可以在Wes McKinney的最近的博客文章,conda-forge和PyData的CentOS时期更多地了解conda-forge的承诺。
认为#9:好的,但如果Continuum Analytics不折腾了,conda不会再工作了吗?
现实:没有,Conda本质上,Continuum Analytics公司通过提供免费托管构建工件为社区服务。所有软件分发都需要由某人,甚至PyPI托管。
的确,即使是conda-forge也将其软件包发布到http://anaconda.org/,这是一个由Continuum Analytics拥有和维护的网站。但在Conda没有什么需要这个网站。事实上,conda中的自定义渠道的创建是有详细记录的,没有什么可阻止某人建立和托管自己的私人分布使用Conda作为包管理器(conda索引是相关的命令)。考虑到conda食谱的开放性和构建系统conda-forge,如果你有理由这样做不会很难反映你自己的服务器上的所有conda-forge。
如果你仍然担心Continuum Analytics - 一个营利公司 - 通过托管conda包为社区服务,你应该也同样担心Rackspace - 一个盈利的公司 - 通过托管Python包索引服务社区。在这两种情况下,一个营利性公司都是社区包裹管理系统目前表现形式的一部分。但在任何情况下,该公司的灭亡都会威胁到构建和分发系统的底层架构,这是完全自由和开源的。如果Rackspace或Continuum消失,社区只需为其依赖的开放式分配找到另一个主机和/或财务赞助者。
认为#10:每个人都应该放弃(conda | pip)和使用(pip | conda)!
现实:pip和conda服务于不同的需求,我们应该更少关注他们如何竞争,更多地关注他们如何一起工作。
正如在神话#2中提到的,Conda和pip是不同的项目,不同的目标读者:pip在任何环境中安装python包; conda安装在conda环境中的任何包装。考虑到在Python的禅意中提出的崇高理想,人们可能希望pip和conda可以以某种方式组合,所以将有一个而且只有一个明显的方式安装包。
但这永远不会发生。这两个项目的目标太不同了。除非pip项目被广泛地重新定义,否则它永远不能有意义地安装和跟踪conda所做的所有非Python包:该架构是Python特定的(正确)以Python为重点。 Pip与PyPI一起旨在成为一个灵活的出版物和分发平台以及Python软件包的管理器,并且它的表现非常出色。
同样,除非conda包被广泛重新定义,它将永远不会取代pip / PyPI作为Python代码的一般发布和分发平台。在其核心,conda关注在多个平台上健壮地运行复杂的多语言软件栈所需的详细依赖关系跟踪类型。 conda的存储库中的每个安装工件都绑定到一个确切的依赖链:通过设计,它不会允许你替换Jython for Python给定的包。你当然可以使用conda来构建一个Jython软件栈,但是每个包都需要一个新的特定于Jython的安装工件 - 这就是为了保持conda用户所依赖的严格依赖链所需要的。 Pip在这里更灵活,但一旦成本是它无法精确定义和解决依赖关系conda。
最后,对pip和conda的关注完全错过了大量的Python代码的目的设计的重新分配器。从平台特定的软件包管理器,如apt,yum,macports和homebrew到像bento,buildout,hashdist和spack这样的跨平台工具,有很多特定的包装解决方案,旨在安装Python(和其他)特定用户。对于我们来说,像Python包装管理局那样,不是作为pip / PyPI的竞争对手,而是作为下游工具,可以利用所有开发和维护pip,PyPI的所有人的英勇努力,这将是更有成果的,和相关工具链。
到哪里去?
因此,似乎我们剩下两种不同的包装解决方案,但是对于许多Python用户来说,它们具有广泛的重叠(即在隔离环境中安装Python包时)。那么社会应该从这里走?我认为我们可以做的主要事情是确保项目(1)尽可能一起工作,和(2)相互学习有点。
Conda
如上所述,conda已经有一个完全打开的工具链,并且处于一个稳定的趋势,完全开放的包(但不完全在那里)。一个明显的方向是通过conda-forge推进社区发展和维护conda堆栈,或许最终使用它来代替conda当前的默认通道。
在我们推进这一点时,我相信,conda和conda-forge社区可以从模仿Python包装管理局的明确和开放的治理模式中受益。例如,PyPA有一个开放的治理模式,明确的目标,新的发展和功能的清晰的路线图,以及明确的沟通和讨论的渠道,以及从根本上社区监督完整的pip / PyPI系统。
另一方面,对于conda和conda-forge,代码(以及很快所有的配方)是开放的,但是系统的治理和控制模型远不够明确。鉴于conda的重要性,特别是在PyData社区,它将有益于所有这一点澄清这一点 - 也许在NumFOCUS组织的保护下。
话虽如此,参与conda-forge的人告诉我,核心团队目前正在解决这个问题,包括生成管理文件,行为准则和加强提案框架。
PyPI / pip
虽然Python包索引似乎有其治理的秩序,有一些方面的conda / conda伪造,我认为将有益于它。例如,目前大多数Python包可以通过几个步骤加载到conda-forge:
在网络上的某个地方发布公共代码版本(在github,bitbucket,PyPI等)
创建指向此代码并列出依赖关系的配方/元数据文件
在conda-forge / staged-recipes上打开一个pull请求
就是这样。一旦pull请求合并,在Windows,OSX和Linux上的二进制版本将自动创建并加载到conda-forge通道。此外,通过github透明地管理和更新软件包,其中软件包更新可以由合作者审核,并在CI系统上线之前进行测试。
我发现这个过程比发布到PyPI的(通过比较相对不透明的和手动的)过程更好,这主要由在本地终端处私人工作的单个用户来完成。也许PyPI可以利用conda-forge的现有构建系统,并创建一个选项来自动构建多平台轮和源分发,并在一个透明的命令中自动推送到PyPI。这绝对是一种可能性。