Python是非常靈活的編程語言,這一特性也體現在它的環境管理中。但是這也可能意味着您的 Python 安裝變得非常混亂。這就出現了大量的環境管理工具試圖來控制這種混亂,但是最終可能也會變得更復雜
在這裏,我會介紹一下目前一些工具的優缺點,以便您可以對如何安裝python環境做出明智的決定。實際上,我們只需要找到自己認爲最方便的方式即可:
爲什麼要做多版本控制以及環境虛擬化
- 虛擬化是爲了避免每個項目之間的依賴衝突,實現項目之間互相隔離的Python環境,提高開發效率
- 項目應該是可複製的:依賴關係越緊密,開發人員實時複製代碼就越容易
- 自包含=可部署:環境和依賴打包發佈越容易,項目部署就越容易
接下來我會從低級工具到高級工具依次討論優缺點,幫助你做出明智決定爲自己省去一些麻煩,我鼓勵您考慮所有能夠滿足您項目需求的方式
到底有那些管理工具?
venv
從3.3版開始,Python標準庫附帶了一個簡單的內置工具venv
$ /python38/Lib/venv/__init__.py # 工具源碼
# 使用內置工具,在當前位置創建一個名爲venv3的虛擬環境
# 如果系統中裝了Python多版本,這裏最好指定Python版本
$ python3 -m venv --symlinks python3 venv3 # 指定Python版本爲python3,python3可直接爲Python解釋器的位置
$ python -m venv venv3 # 不指定Python版本
$ python3 -m venv --symlinks python3 . # 直接當前位置創建虛擬環境
$ cd /path/Scripts/ # 進入虛擬環境的位置
$ activate # 啓動虛擬環境
$ deactivate # 推出虛擬環境
激活後,pip install(獨立軟件包或來自requirements 文件)將按預期工作。要打包一個虛擬環境以在別處複製,您只需要生成一個包含環境內容的requirements 文件
$ pip freeze > requirements.txt
如果環境處於活動狀態,則會生成一個requirements 文件,該文件可以安裝到另一個系統上的虛擬環境中
$ pip install -i requirements.txt
優點:
- Python附帶,無需其他工具
- 創建一個標準虛擬環境:requirements.txt 適用於任何使用 pip 的環境管理器
缺點:
- 不能集中管理虛擬環境
- 只能使用pip安裝依賴包
改進:
如果你是一個Python老鳥,可以修改源碼來更加完美地滿足自己的需求,我就這麼幹過,但是這意味着每次裝一個Python解釋器,都需要把自己寫的init.py文件替換一下,缺點也明顯,不過可以自己DIY也是不錯的
$ /python38/Lib/venv/__init__.py # 工具源碼
virtualenv
實際上,venv是將virtualenv功能的子模塊引入到了Python 3.3+標準庫中,使用方法其實和venv幾乎一樣,可以去搜索一下,有很多使用教程的
virtualenv + virtualenvwrapper-win 是極簡組合,也是最古老的組合,這也是我習慣用的管理器,其實Python 自帶的venv工具,自己也可以把 virtualenvwrapper-win 中的 workon命令融合進去,這個命令是最常用的命令
$ /python38/Lib/venv/__init__.py # 修改一下venv源碼即可,也是很簡單的,但是新手最好不要修改
優點:
- 創建與venv相同的標準虛擬環境,可與大多數Python版本管理工具配合
- 集成了一些高級功能,例如能夠爲環境創建引導腳本
缺點:
- 和venv工具一樣
pyenv
pyenv本身僅控制已安裝的Python版本,而不控制虛擬環境。當然,在pyenv控制的Python版本中,我們可以輕鬆地使用venv或virtualenv來構建虛擬環境,不過也可以使用pyenv-virtualenv插件來管理虛擬環境
優點:
- 一站式管理所有已安裝的Python版本
- 快速設置每個項目的默認Python版本和虛擬環境,自動切換項目目錄
- 等等
缺點:
- 安裝、設置、操作複雜(操作複雜是指功能太多,極簡主義就是很少的功能解決特定的需求)
pipenv
Pipenv會自動幫你管理虛擬環境和依賴文件,並且提供了一系列命令和選項來幫助你實現各種依賴和環境管理相關的操作,可以通過Pipfile配置文件,實現更多的操作,甚至是下載指定的Python版本。可以說是環境管理的大集合,無所不能
優點:
- Python Packaging Authority正式支持
- 用於項目,虛擬環境和包管理的單一工具
- 與pyenv和conda配合使用可很好地處理Python環境
- 每個項目經過驗證的確定性依賴
缺點:
- 與其他管理工具不兼容,因此需要在項目和用戶之間一致使用
- 依賴解析慢
poetry
同樣,poetry 包括環境控制和依存關係解析,但poetry 更具體地針對Python軟件包開發而不是常規項目控制
也可以說poetry不想pipenv那樣包羅萬象,想做一個極致的包管理器
優點:
- 用於項目,虛擬環境和包管理的單一工具
- 每個項目經過驗證的確定性依賴
- 集成的Python軟件包構建/發佈工具
缺點:
- 依賴解析慢
- 需要特定工具的安裝和更新,而不是使用庫存包管理器
- 工具更適合於打包項目,而不是應用程序開發
- 不與其他環境/程序包管理器兼容
anaconda
Python包管理一直面臨一個主要問題-儘管Python包可能需要非Python依賴項(例如,Python中幾乎所有數字工具都基於C / C ++),但無法控制這些包有意義地跟蹤這些依賴項。較早的sdist(“源代碼分發”)軟件包分發版只能共享源代碼,因此需要在主機上使用兼容的編譯器來完全構建,軟件包-編譯器工具鏈之間的差異可能會在軟件包安裝中引入錯誤。儘管通過遷移到wheel發行版(包括共享對象.so文件等已編譯的依賴項)極大地改善了這一點,但是Python的程序包樹並未版本跟蹤非Python的依賴項(因此,例如,他們實際上並不瞭解類似編譯的依賴項中的版本更改)。
這個以及其他一些問題(例如在pip中缺少嚴格的依賴解析器)促使Anaconda的發展-一個多合一的Python發行版(儘管其行爲與您習慣的普通Python可調用函數相同)和環境管理器稱爲conda,以及新的程序包分發格式。整個過程都隨圖形安裝程序一起提供,該安裝程序還將向啓動腳本中注入指令,以便默認的Python來自Anaconda發行版。
這是Anaconda / conda與我們在此討論的其他管理器之間的最大區別-儘管其他一切都基於pip構建,並使用Python軟件包的標準wheel 格式,conda從頭開始重新設計環境中打包的方式,並採取了截然不同的設計理念。簡而言之:pip可在任何環境中安裝python依賴項,而conda可在conda環境中安裝任何依賴項。在conda環境中,您可以對依賴項進行細粒度的控制,其代價是只能在conda環境框架中發揮作用-程序包管理器與環境密不可分,並且依賴於包裝結構和環境規範與其他Python工具不兼容。相比之下,pip在處理Python依賴項的環境方面是完全通用的(即使在pipenv和poetry)中也被廣泛使用),並且可以安裝到任何運行Python的環境中,包括conda環境。
所有這些意味着,Anaconda及其相關工具可以真正強大地啓動並運行本地環境,並輕鬆管理自己的項目。因此,它是數據科學家的通用解決方案,這些開發者通常在自己的定製環境中運行代碼,並且特別需要對數字包中已編譯的依存關係進行乾淨處理。但是,與其他系統集成要困難得多,尤其是在項目生產部署時。
優點:
- 集成的Python分發,環境和包管理
- 有意義地處理非Python依賴項
- 包括嚴格的依賴解決方案(相當於pipenv和poetry)
- 附帶有現成的數據科學堆棧
- 跨平臺工作
缺點:
- 軟件包管理未與標準軟件包存儲庫集成,這意味着仍然有必要退回pip安裝
- 不與任何其他環境管理器集成,沒有交叉兼容性
- 與conda和pip安裝的混合搭配可能很難複製
- 全新的Python軟件包開發工具鏈
docker
就Python環境管理而言,說Docker可能有點奇怪,但它對環境管理至關重要,因此必須包括在內。與其他工具不同,Docker根本就不是Python環境管理器-而是容器管理器。每個Docker容器都運行一個輕量級的環境,其中包括位於隔離資源之上的所有代碼,系統工具和庫。從開發人員的角度來看,該容器就是運行在Linux環境下的獨立計算機,而沒有整個虛擬機的資源開銷-在同一臺計算機上可以同時運行多個容器。全棧開發人員可能會同時爲前端,後端和數據庫實例運行單獨的容器。這使我們可以完全控制代碼環境中的所有內容,甚至可以控制底層系統依賴性,還可以創建一個可移植的容器,該容器也即該環境可以在運行Docker的任何地方精確克隆
優點:
- 完全控制我們所有的依賴關係,直至系統級別-甚至可以使用本文中的任何環境管理器
- 明確指定所有指令以複製代碼環境
- 容器可以很容易地打包和運輸以在生產環境中運行
- 通用指令可以內置到新的基礎映像中,並在項目之間重複使用
- 可以以編程方式定義在單個docker-compose規範中獨立運行的多個服務之間的交互
缺點:
- 全新的技能學習
總結
我們經常說到依賴管理,其實主要是發佈library庫依賴和項目應用依賴,分別對應的是setup.py 與 Pipfile(或者requirements.txt)。對於我們初學者很少會發布library庫到pypi,所以庫依賴我們很少接觸。最多的還是利用github發佈項目應用,只需要一個Pipfile(或者requirements.txt)依賴文件即可
以上所有的環境管理我都用過,但是最終我還是迴歸了 virtualenv + virtualenvwrapper-win,因爲你的開發環境(也即操作系統)可能不是固定不變的,那麼簡單快捷不需要配置的環境管理纔是最方便的
所以說,大道至簡,像我這樣的初級程序員一般不會去搞有強依賴性的項目,不需要項目依賴追蹤和擴展,使用 virtualenv + virtualenvwrapper-win 就足夠方便了,或者自己手動修改一下Python 自帶的venv工具,完全已經夠用了,再結合一下Docker可以輕鬆快速地完成項目開發部署