苦口婆心:別再 pip install 了!
本文閱讀需要約 5 分鐘
?小帥b?
Hi,我是小帥b。
你在寫(xiě) Python 項(xiàng)目的時(shí)候是不是常常會(huì)使用 pip install 來(lái)安裝相關(guān)的依賴(lài),但這其實(shí)到后面會(huì)產(chǎn)生一些不必要的麻煩,至于什么麻煩后面會(huì)說(shuō)。

最近看到了篇《Why you should use?python -m pip》,作者非常苦口婆心的勸人們一定要使用?python -m pip?而不是直接?pip,我覺(jué)得寫(xiě)得挺好的,隨即給翻譯了一波,希望對(duì)你有幫助。
首先,當(dāng)你執(zhí)行?python -m pip?的時(shí)候,是在指定 Python 解釋器來(lái)執(zhí)行 pip。
比如當(dāng)你這么執(zhí)行:
/usr/bin/python3.7 -m pip
就是在指定在 /usr/bin/python3.7 下的解釋器來(lái)執(zhí)行 pip。
為啥要使用 python -m pip 而不是直接 pip/pip3 呢?你可能會(huì)說(shuō),“行了行了,我都知道,但我就是想直接通過(guò) pip 命令來(lái)執(zhí)行 pip,你吹啊?”
答案是:“可以啊,不過(guò)呢,但你這么做的話(huà),你到時(shí)候會(huì)很亂很麻煩”。
我來(lái)給你舉個(gè)例子。
比如說(shuō)我的電腦現(xiàn)在安裝了兩個(gè) Python 的版本(可能還更多),分別是 Python3.7 和 3.8,那么現(xiàn)在,我直接在終端執(zhí)行 pip 去 install,請(qǐng)問(wèn)它會(huì)為哪個(gè)版本的 Python 解釋器進(jìn)行安裝?
我想你可能會(huì)一臉懵逼,因?yàn)闆](méi)有更多的細(xì)節(jié),所以你不知道。
首先你要知道我的環(huán)境變量 PATH 設(shè)置的是什么,比如 /usr/bin 和 /usr/local/bin,誰(shuí)在前誰(shuí)在后。
這時(shí)候你可能會(huì)說(shuō),我只要記住我在不同的目錄分別安裝了 Python3.7 和 Python3.8,我就會(huì)知道 PATH 上哪個(gè) Python 版本在前面。
但假設(shè)你手動(dòng)安裝了兩個(gè) Python 版本,也許你的系統(tǒng)本身帶有了 Python3.7.3 版本,然后你還安裝了 Python3.7.5,這時(shí)候兩個(gè)版本都安裝在了 /usr/local/bin 下,那么你現(xiàn)在能知道 pip 和哪個(gè) Python 解釋器相關(guān)么?
答案就是你依然不知道,除非你知道什么時(shí)候安裝了什么 Python 版本,并且知道最后一次寫(xiě)入 /usr/local/bin/pip 的是哪個(gè),否則你壓根不會(huì)知道執(zhí)行 pip 的時(shí)候用的是哪個(gè)版本的解釋器。
你又要說(shuō)了,那我總是安裝最新的版本不就好了,比如我安裝最新的 Python3.8.0,它比 3.7.5 要新。
好吧,但是當(dāng) Python3.7.6 版本出來(lái)的時(shí)候會(huì)怎么樣呢?你的 pip 命令會(huì)將使用 Python3.8 轉(zhuǎn)化為 Python3.7。
而當(dāng)你使用?python -m pip?,上面所有的歧義立馬消失,比如說(shuō)我使用 python3.8 -m pip,那么我肯定知道 pip 用的是 Python3.8 解釋器來(lái)安裝使用。
如果你是 Windows 用戶(hù),你使用 python -m pip 還有一個(gè)好處,那就是可以讓 pip 自我更新。
因?yàn)楫?dāng)你直接執(zhí)行 pip install --upgrade pip 的時(shí)候,Windows 系統(tǒng)不會(huì)讓你覆蓋 pip.exe, 但你在前面加個(gè) python -m,你就可以避免這個(gè)問(wèn)題,因?yàn)檫@時(shí)候運(yùn)行的是 python.exe,而不是 pip.exe。
那我在激活環(huán)境下應(yīng)該怎么搞?通常當(dāng)我向一群人解釋這一點(diǎn)時(shí),難免會(huì)有人說(shuō),“我都是在虛擬環(huán)境中操作的,所以你說(shuō)的這一點(diǎn)根本不適合我”。
總是使用虛擬環(huán)境這點(diǎn)做得不錯(cuò),但老實(shí)說(shuō),即使在完全沒(méi)有必要的情況下,我仍然主張使用?python -m pip。
首先,如果你使用的是 Windows 系統(tǒng),你還是需要使用 python -m pip,這樣你才可以在你當(dāng)前環(huán)境中更新它。
其次,即使你使用的是其他系統(tǒng),我還是會(huì)說(shuō)應(yīng)該使用?python -m pip,因?yàn)樗谌魏吻闆r都能工作。不僅僅是在你忘記激活虛擬環(huán)境時(shí)防止發(fā)生錯(cuò)誤,而且還意味著任何看到你這么操作的人都能學(xué)到這一點(diǎn)。
就我個(gè)人來(lái)說(shuō),我不認(rèn)為你少打幾個(gè)字就能在最佳的實(shí)踐中走捷徑。它還可以防止你在忘記激活虛擬環(huán)境的時(shí)候,寫(xiě)一些自動(dòng)化腳本而發(fā)生錯(cuò)誤。
就說(shuō)我自己吧,我使用任何依賴(lài)于解釋器的工具,我都會(huì)使用?-m,不管是不是激活了環(huán)境,都能非常有目的且清晰的說(shuō)明我希望使用什么 Python 解釋器。
不要啥都安裝到你的全局解釋器里面雖然我們?cè)谡務(wù)撊绾伪苊馀獊y你的 Python 安裝,但我還要指出一點(diǎn):當(dāng)你在本地開(kāi)發(fā)的時(shí)候,永遠(yuǎn)不要把東西安裝到你的全局 Python 解釋器里面去。如果它是你系統(tǒng)安裝的 Python,那么你安裝了一個(gè)操作系統(tǒng)所依賴(lài)的不兼容版本的庫(kù),可能會(huì)破壞你的系統(tǒng)。
即使你安裝了自己的 Python 版本,我仍然強(qiáng)烈建議你不要在本地開(kāi)發(fā)的時(shí)候直接都把包安裝進(jìn)去。因?yàn)槟阕罱K會(huì)在你的項(xiàng)目之間混合各種可能互相沖突的包,你對(duì)每個(gè)項(xiàng)目真正的依賴(lài)都會(huì)很模糊,等等。
所以使用虛擬環(huán)境將你的個(gè)人項(xiàng)目和工具互相隔離開(kāi)來(lái)要好很多。
在 Python 社區(qū)中有兩種環(huán)境的類(lèi)型:虛擬環(huán)境和 conda 環(huán)境。
甚至還有一種方法可以以隔離的方式來(lái)安裝 Python 工具。
如果你需要安裝工具為了讓 Python 工具得到隔離,我會(huì)使用?pipx?來(lái)安裝,因?yàn)槊總€(gè)安裝的工具都會(huì)擁有自己的虛擬環(huán)境,所以它們不會(huì)互相沖突。如果你想單獨(dú)安裝 Black 模塊,你可以直接安裝,不會(huì)意外破壞你安裝的 mypy 模塊。
如果你的項(xiàng)目需要一個(gè)環(huán)境(沒(méi)有使用 conda 的情況下)當(dāng)你需要為項(xiàng)目創(chuàng)建虛擬環(huán)境時(shí),我個(gè)人總會(huì)使用 venv 和虛擬環(huán)境。它包含在 Python 的標(biāo)準(zhǔn)庫(kù)中,所以它始終可以通過(guò)?python -m venv?獲取的。
一丟丟小歷史:我實(shí)際上刪除了用來(lái)創(chuàng)建虛擬環(huán)境的 pyvenv 命令,這正是你應(yīng)該使用 python -m pip 而不是 pip 的原因;僅從命令看,你無(wú)法知道 pyvenv 命令為哪個(gè)解釋器創(chuàng)建了一個(gè)虛擬環(huán)境;記住,你可以不用激活環(huán)境來(lái)使用其中的解釋器;執(zhí)行 .venv/bin/python 和你激活了環(huán)境并輸入 python 一樣有效。
現(xiàn)在有人仍然喜歡 virtualenv,因?yàn)樗?Python2 上可用,并且有一些其他的額外功能。就我個(gè)人而言,我不需要這些額外的功能,并且擁有 venv 集成,就意味著我不需要使用 pipx 在每臺(tái)機(jī)器安裝 virtualenv。但是如果你創(chuàng)建虛擬環(huán)境還需要 venv 一些不能夠滿(mǎn)足的需求,那么你可以看看 virtualenv 是否滿(mǎn)足你的需求。
如果你是 conda 用戶(hù)如果你是 conda 用戶(hù),那么你可以使用 conda environments 來(lái)達(dá)到與 venv 所提供的虛擬環(huán)境同樣的效果。
我不打算談?wù)撃闶欠駪?yīng)該針對(duì)你的情況使用 conda 而不是 venv。但如果你在使用 conda 時(shí),你應(yīng)該知道你可以為你的項(xiàng)目創(chuàng)建 conda 環(huán)境而不是將所有的東西都安裝在你的基礎(chǔ)環(huán)境中,并且能夠清楚的知道你的項(xiàng)目依賴(lài)了什么。(這也是為什么說(shuō)要使用 miniconda 而不是 anaconda,因?yàn)榍罢叽笮∵€沒(méi)有后者的十分之一。)
容器在容器中工作是另一種選擇,因?yàn)榇藭r(shí)你可以跳過(guò)環(huán)境,因?yàn)檎麄€(gè)「機(jī)器」就是環(huán)境,只要你沒(méi)有將 Python 安裝到容器系統(tǒng)中,你就可以自由地進(jìn)行全局安裝,以保持容器的簡(jiǎn)單清晰。
重復(fù)一下我的觀點(diǎn),真的想讓大家明白這一點(diǎn)不要安裝到全局的 Python 解釋器中!在本地開(kāi)發(fā)的時(shí)候,一定要使用一個(gè)環(huán)境!
我無(wú)法計(jì)算我有多少次不得不幫助那些 pip 安裝錯(cuò)地方的人。還有那些破壞自己系統(tǒng),或者想知道為什么他們安裝東西會(huì)產(chǎn)生沖突等等,因?yàn)樗麄儜械迷诒镜貦C(jī)器上設(shè)置環(huán)境。
所以,請(qǐng)理智一點(diǎn),使用?python -m pip,并始終使用虛擬環(huán)境。
推薦閱讀:
記得將我的公眾號(hào)設(shè)為?星標(biāo),覺(jué)得本文還不錯(cuò)的話(huà)就來(lái)個(gè)三連,謝啦~
我們下回見(jiàn),peace!

?