建立成功的Python環(huán)境的4個(gè)基本工具
選擇的這些工具將簡(jiǎn)化你的 Python 環(huán)境,以實(shí)現(xiàn)順暢和一致的開(kāi)發(fā)實(shí)踐。
Python 是一門出色的通用編程語(yǔ)言,經(jīng)常作為第一門編程語(yǔ)言來(lái)教授。二十年來(lái),我為它撰寫了很多本書,而它仍然是我的首選語(yǔ)言。雖然通常來(lái)說(shuō)這門語(yǔ)言是簡(jiǎn)潔明了的,但是(正如 xkcd 諷刺的),從來(lái)沒(méi)有人說(shuō)過(guò)配置 Python 環(huán)境也是一樣的簡(jiǎn)單。
一個(gè)復(fù)雜的Python環(huán)境。 xkcd
在日常生活中有很多使用 Python 的方法。我將解釋我是如何使用這些 Python 生態(tài)系統(tǒng)工具的。但坦誠(chéng)的說(shuō),我仍在尋找更好的替代品。
使用 pyenv 來(lái)管理 Python 版本
我發(fā)現(xiàn)在機(jī)器上運(yùn)行一個(gè)特定版本的 Python 的最好方法是使用 pyenv
。這個(gè)軟件可以在 Linux、Mac OS X 和 WSL2 上工作:這是我通常關(guān)心的三個(gè) “類 UNIX” 環(huán)境。
安裝 pyenv
本身有時(shí)會(huì)有點(diǎn)棘手。一種方法是使用專用的 pyenv 安裝程序,它使用 curl | bash
方法來(lái)進(jìn)行(詳見(jiàn)其說(shuō)明)。
如果你是在 Mac 上(或者你運(yùn)行 Homebrew 的其他系統(tǒng)),你可以按照這里的說(shuō)明來(lái)安裝和使用 pyenv
。
按照說(shuō)明安裝和設(shè)置了 pyenv
之后,你可以使用 pyenv global
來(lái)設(shè)置一個(gè) “默認(rèn)的” Python 版本。一般來(lái)說(shuō),你會(huì)選擇你的 “首選” 版本。這通常是最新的穩(wěn)定版本,但如果有其他考慮因素也可能做出不同的選擇。
使用 virtualenvwrapper 讓虛擬環(huán)境更簡(jiǎn)單
使用 pyenv
安裝 Python 的一個(gè)好處是,你所有后繼安裝的 Python 解釋器環(huán)境都是你自己的,而不是操作系統(tǒng)層面的。
雖然在 Python 本身內(nèi)部安裝東西通常不是最好的選擇,但有一個(gè)例外:在上面選擇的 “首選” Python 中,安裝并配置 virtualenvwrapper
。這樣你就可以瞬間創(chuàng)建和切換到虛擬環(huán)境。
我在這篇文章中具體介紹了如何安裝和使用 virtualenvwrapper
。
這里我推薦一個(gè)獨(dú)特的工作流程:你可以制作一個(gè)可以大量重復(fù)運(yùn)行的虛擬環(huán)境,用來(lái)做運(yùn)行器。在這個(gè)環(huán)境中,可以安裝你最喜歡的運(yùn)行器 —— 也就是你會(huì)經(jīng)常用來(lái)運(yùn)行其他軟件的軟件。就目前而言,我的首選是 tox
。
使用 tox 作為 Python 運(yùn)行器
tox 是一個(gè)很好的工具,可以讓你的 Python 測(cè)試自動(dòng)化。在每個(gè) Python 環(huán)境中,我都會(huì)創(chuàng)建一個(gè) tox.ini
文件。無(wú)論我使用什么系統(tǒng)做持續(xù)集成,都可以運(yùn)行它,我可以用上面文章中描述的 virtualenvwrapper
的 workon
語(yǔ)法在本地運(yùn)行同樣的東西:
$ workon runner
$ tox
這個(gè)工作流程之所以重要,是因?yàn)槲乙诙鄠€(gè)版本的 Python 和多個(gè)版本的依賴庫(kù)中測(cè)試我的代碼。這意味著在 tox
運(yùn)行器中會(huì)有多個(gè)環(huán)境。一些會(huì)嘗試在最新的依賴關(guān)系中運(yùn)行,一些會(huì)嘗試在凍結(jié)的依賴關(guān)系中運(yùn)行(接下來(lái)會(huì)有更多的介紹),我也可能會(huì)用 pip-compile
在本地生成這些環(huán)境。
附注:我目前正在研究使用 nox 作為 tox
的替代品。原因超出了本文的范疇,但值得一試。
使用 pip-compile 進(jìn)行 Python 依賴性管理
Python 是一種動(dòng)態(tài)編程語(yǔ)言,這意味著它在每次執(zhí)行代碼時(shí)都會(huì)加載其依賴關(guān)系。能否確切了解每個(gè)依賴項(xiàng)的具體運(yùn)行版本可能意味著是平穩(wěn)運(yùn)行代碼還是意外崩潰。這意味著我們必須考慮依賴管理工具。
對(duì)于每個(gè)新項(xiàng)目,我都會(huì)包含一個(gè) requirements.in
文件,(通常)只有以下內(nèi)容:
.
是的,沒(méi)錯(cuò)。只有一個(gè)點(diǎn)的單行。我在 setup.py
文件中記錄了 “寬松” 的依賴關(guān)系,比如 Twisted>=17.5
。這與 Twisted==18.1
這樣的確切依賴關(guān)系形成了鮮明對(duì)比,后者在需要一個(gè)特性或錯(cuò)誤修復(fù)時(shí),難以升級(jí)到新版本的庫(kù)。
.
的意思是 “當(dāng)前目錄”,它使用當(dāng)前目錄下的 setup.py
作為依賴關(guān)系的來(lái)源。
這意味著使用 pip-compile requirements.in > requirements.txt
會(huì)創(chuàng)建一個(gè)凍結(jié)的依賴文件。你可以在 virtualenvwrapper
創(chuàng)建的虛擬環(huán)境中或者 tox.ini
中使用這個(gè)依賴文件。
有時(shí),也可以從 requirements-dev.in
(內(nèi)容:.[dev]
)生成 requirements-dev.txt
,或從 requirements-test.in
(內(nèi)容:.[test]
)生成 requirements-test.txt
。
我正在研究在這個(gè)流程中是否應(yīng)該用 dephell 代替 pip-compile
。dephell
工具有許多有趣的功能,比如使用異步 HTTP 請(qǐng)求來(lái)下載依賴項(xiàng)。
結(jié)論
Python 的功能既強(qiáng)大又賞心悅目。為了編寫這些代碼,我依靠了一個(gè)對(duì)我來(lái)說(shuō)很有效的特定工具鏈。工具 pyenv
、virtualenvwrapper
、tox
和 pip-compile
都是獨(dú)立的。但是,它們各有各的作用,沒(méi)有重疊,它們一起打造了一個(gè)強(qiáng)大的 Python 工作流。