Conda:誤解與迷思
翻譯自這裡
我試著儘可能簡潔,但如果你想要跳過這篇文章,並得到討論的要點,你可以閱讀每個標題以及下面的摘要。
神話#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。這絕對是一種可能性。