雖然後來 Python 寫得越來越少,但是還是要和一些使用 Python 的專案打交道,並且發現許多同學對於 Python 的虛擬環境,包管理等問題並不是很熟悉,因此寫這篇部落格梳理一下,希望對其他人有所幫助。
TL;DR
- 使用 pyenv 切換不同版本的 python
- 使用 poetry 在不同 python 下管理專案依賴和虛擬環境
- 絕不使用 sudo pip install 安裝 python 包
- 絕不使用 sudo make install 安裝 python
Python 版本選擇問題
除了特殊的本身就對於多版本軟體有良好支援的發行版(例如 NixOS)以外,目前來說(2021 年)系統上安裝的 python 最多隻有兩個大版本,2.x 和 3.x,這些 python 已經被系統包管理器處理好了各自的依賴關係,有時候甚至會用到系統關鍵元件中去。因此,除非知道自己在做什麼,絕對不要使用 sudo pip install
或者 make install
來在全域性安裝 python 庫 或者全新的 python 版本。
我所使用的多版本管理方案是 pyenv,能夠在不同的 python 版本中自由切換,類似於 rbenv
或者 opam switch
。
如果你只想要 python3,對小版本號沒有太苛刻的需求,那麼沒必要去使用 pyenv
,可以在開發時直接使用後文提到的 poetry
來管理專案。
後續可以透過poetry env use ~/.pyenv/shims/python
來設定 poetry 使用按照的 pyenv 的python
直譯器。
Poetry 和虛擬環境
在開發一個專案的時候,很可能需要安裝許多軟體包,這些軟體包有可能還需要指定版本,因此與本地版本衝突,這時我們就需要虛擬環境進行隔離。虛擬環境是一個乾淨的 python 環境,在這個環境中進行 python 軟體包的安裝並不會影響其他虛擬環境或者系統環境, python3.3 之後通常使用自帶的 venv 來實現。
在開發時,很常見的需求是需要復現環境,安裝需要的軟體包,透過 requirements.txt (原生 python)或者透過 Pipfile (pipenv)都可以,前者對於軟體包的互相依賴沒有很好的支援,後者的 lock 時間在專案稍微大一點的時候就令人發怵。
poetry 是一個更現代的 python 軟體包管理器。
常見的使用方式
新建一個專案:
poetry new <project-name>
。在當前專案中新增依賴:
poetry add <package-name>
,加上--dev
引數表示為開發依賴。安裝所有的依賴:
poetry install
。在虛擬環境中執行某個指令碼或者程式:
poetry run <cmd>
。其中<cmd>
可以是python <filename>.py
,也可以是一個存在於虛擬環境中的可執行檔案的名字,例如flask
,fava
等等。刪除現有的虛擬環境:
poetry env rm pytyon
。如果需要使用國內映象,則編輯
pyproject.toml
,在pyproject.toml
里加入1 2 3
[[tool.poetry.source]] name = "zju" url = "https://mirrors.zju.edu.cn/pypi/web/simple"
安裝個人使用的軟體包
透過 pip install --user
能夠為當前環境中 pip 所對應的 python 版本 在使用者目錄下安裝軟體包。如果對於個人所需要使用的軟體包,同時系統包管理器又沒有提供的,推薦在(使用 pyenv )選擇了合適的 python 版本之後,用這種方式安裝。
同時,需要將安裝之後的 bin
路徑新增到環境變數中,通常是 $HOME/.local/bin
。新增後即可直接在命令列中使用了。
進階使用
構建軟體包並且指定可執行的指令碼
執行 poetry build
即可構建軟體包。
指定可執行程式的函式入口:
|
|
表示安裝了最終構建的 wheel 包以後,有一個可執行檔案叫做 abc
,執行之後會執行 bca/abc.py
中的 main
函式的內容。
透過 Poetry 執行 Python 服務和指令碼
有時候,系統沒有相應的軟體包可供安裝(例如一些 GitHub 上的自動指令碼),那麼使用 poetry
來配置並執行也是一個不錯的選擇。
只需要建立一個工程,只使用 poetry add <...>
和 poetry run <...>
即可,既不會影響本地的環境,也可以在遷移和升級的時候更方便。不需要編寫任何程式碼,。
對於一些需要使用守護程序執行的服務,可以使用 systemd
管理。以下是我使用的一個 Unit file:
|
|