核心開發人員和加拿大人Mariatta在Twitter上詢問了有關python -m pip的問題,以及誰向她介紹了該慣用法並要求其提供解釋它的參考資料:
我以前就了解到我們應該使用『python -m pip install……』,而不是簡單地使用『pip install ...』,但現在我不記得這條消息的 來源了。可能來自@brettsky或@zooba,你們有關於這方面的演講或博文嗎,以便我可以與別人分享?
——Mariatta (@mariatta) October 29,2019
現在我不確定是不是我告訴了Mariatta關於python -m pip的事,但很有可能是我,因為我從2016年起就一直要求讓它成為PyPI上提供的關於如何安裝包的說明。因此,這篇博客文章的目的是解釋python -m pip是什麼,以及為什麼您在運行pip時應該使用它。
python -m pip是什麼?首先,python -m pip會使用您指定為python的Python解釋器來執行pip。因此,/usr/bin/python3.7 -m pip表示您正在執行位於/usr/bin/python3.7的解釋器的pip。如果您不熟悉這個標誌以及它是如何工作的,您可以閱讀有關-m的文檔(它非常方便)。
為什麼使用 python -m pip 而不是 pip/pip3?所以您可能會說,「好的,但是我不能通過執行pip命令來運行pip嗎?」答案是「可以,但是您對它的控制會更少」,我將用一個例子來解釋我所說的「控制會更少」是什麼意思。
假設我已經安裝了Python的兩個版本,比如Python 3.7和3.8(由於Python會預先安裝在macOS和Linux上,這對人們來說是很常見的,更不用說您之前已經安裝了Python 3.7,您還是會安裝Python 3.8來使用它)。現在,如果您在您的終端中鍵入pip,那麼它將為哪個Python解釋器安裝庫呢?
在沒有更多的細節的情況下,您的答案是您不知道。首先,您必須知道我的PATH設置是什麼,比如/usr/bin是在/usr/local/bin之前還是之後(這些是安裝Python的常見位置,通常優先安裝於/usr/local/目錄)。好的,只要您記得您安裝Python 3.7和3.8的地方,它們是不同的目錄,您就會知道哪個版本的pip在PATH上先出現。假設您都是手動安裝它們的,也許您的作業系統附帶了Python 3.7.3,而您又安裝了Python 3.7.5。在這種情況下,Python的兩個版本都安裝在/usr/local/bin中。現在您能告訴我pip與哪個解釋器相關聯嗎?
答案是您仍然不知道。除非您知道您在什麼時候安裝了每個版本,從而就會知道被寫到/usr/local/bin/pip的最後一個pip副本是什麼,否則您就不知道哪個解釋器的pip將被用於執行pip命令。現在您可能會說,「我總是會安裝最新的版本,這意味著Python 3.8.0是最後安裝的,因為它比3.7.5更新。」好的,但是當Python 3.7.6出現時會發生什麼呢?您的pip命令將會從使用Python 3.8變為使用Python 3.7。
但是當您使用python -m pip時,而python是您希望使用的特定解釋器時,所有上述的模糊性都消失了。如果我使用python3.8 -m pip,那麼我就知道pip將會在我的Python 3.8解釋器中使用和安裝(如果我使用的是python3.7,那麼情況也一樣)。
如果您是在Windows上運行,使用python -m pip還有一個額外的好處,那就是它可以讓pip自我更新。基本上,當您執行pip install --upgrade pip時,系統會認為pip.exe正在運行,因此,Windows是不會讓您覆蓋pip.exe的。但是,如果您執行python -m pip install --upgrade pip,就可以避免這個問題,因為正在運行的是python.exe,不是pip.exe。
當我在一個激活的環境中時會怎樣呢?通常當我向一群人解釋這一點時,不可避免地會有人說:「我一直使用虛擬環境,所以這對我不適用」。首先,總是使用虛擬環境會把工作做得很好(我將在這篇博客文章的後面討論為什麼這是一個最佳實踐)!但說實話,我仍然主張使用python -m pip,即使在嚴格來說沒有必要的情況下也是如此。
首先,如果您是在Windows上,您會想要繼續使用python -m pip,以便能夠在您的環境中更新pip。
其次,即使您在另一個作業系統上,我想說您也應該使用python -m pip,因為它在任何情況下都能工作。如果您碰巧忘記了激活您的環境,那它不僅能防止您犯錯誤,而且還意味著任何人都能在您身邊學習到最佳實踐。就我個人而言,我不覺得為一個您不經常執行的命令節省10次按鍵就可以讓您從通用最佳實踐中採用一個捷徑變得合理。它還可以防止您意外地編寫一些自動化腳本,這些腳本在您忘記激活環境時會執行錯誤的操作。
>>> 今日籤到口令:em4q <<<
就我個人而言,我所使用的任何工具,如果它的執行依賴於它所運行的解釋器,那我總是會使用-m來激活環境或不激活,以便我想要使用/影響的Python解釋器更具目的性和明確性。
總是使用虛擬環境! 不要安裝到您的全局解釋器中!雖然我們討論的主題是如何避免搞混您的Python安裝,但我想指出的是,當您在本地進行開發時,您絕不應該將其他東西安裝到您的全局Python解釋器中(容器是另一回事)!如果是Python的系統安裝,那麼如果您安裝了一個作業系統所依賴的不兼容版本的庫,就可能會導致系統崩潰。
但是,即使您安裝了自己的Python副本,我仍然強烈建議在本地開發時不要直接安裝到Python中。您最終會在您的項目之間混合不同的包,它們可能會相互衝突,您並不清楚您的每個項目真正依賴什麼,等等。最好是使用環境來隔離您的各個項目和工具。在Python社區中有兩種類型的環境:虛擬環境和conda環境。甚至還有一種以獨立方式安裝Python工具的方法。
如果您需要安裝一個工具要獨立安裝一個工具,我將會使用pipx。每個工具都會有自己的虛擬環境,這樣它們就不會相互衝突。例如,如果您想單獨安裝Black,您就可以這樣做,而不會意外地破壞您的mypy的單獨安裝。
如果您想為您的項目創建一個環境 (而且您沒有使用conda)當您需要為一個項目創建一個環境時,我個人總是會使用venv和虛擬環境。它包含在Python的stdlib中,所以您總是可以通過Python -m venv使用它(只要您不是在Debian/Ubuntu上,否則您可能必須安裝python3-venv apt包)。一點小歷史:實際上我刪除了Python用於使用venv創建虛擬環境的舊的pyvenv命令,原因是您應該使用Python -m pip而不是pip;僅從該命令來看,您無法通過舊的pyvenv命令知道您正在為哪個解釋器創建虛擬環境。請記住,您不必激活該虛擬環境來使用它所包含的解釋器;只要您激活該環境,然後鍵入python,.venv/bin/python就會運行了。
現在有些人仍然更喜歡virtualenv,因為它在Python2上可用,而且還有其他一些額外的特性。就我個人而言,我不需要這些額外的功能,而且集成了venv就意味著我不需要使用pipx在每臺機器上安裝virtualenv。但是,如果venv不能滿足您的需要,而您又需要一個虛擬環境,那麼您可以看看virtualenv是否能滿足您的需要。
如果您是一個conda用戶如果您是一個conda用戶,那麼您可以使用conda環境獲得與venv提供的虛擬環境相同的效果。我不打算深入討論您是否應該在您的情況中使用conda而不是venv,但是如果您發現自己使用conda然後知道您可以(也應該)為您的工作創建conda環境而不是將所有東西安裝到您的基本環境中,並對您的項目所依賴的東西有一個清晰的理解(這也是您應該使用miniconda而不是anaconda的一個很好的理由,前者的安裝大小比後者的十分之一還小)。
容器必不可少在容器中工作是另一種選擇,因為此時您可以跳過創建環境的部分,因為整個「機器」就是環境。只要您沒有將容器安裝到系統Python中,您就可以自由地進行全局安裝,以保持容器的簡單和直接。
我再重複一遍,嘗試把這個要點講清楚……不要安裝到您的全局Python解釋器中!在進行本地開發時,請始終嘗試使用虛擬環境!
我數不清有多少次我不得不幫助那些認為pip正在安裝到一個Python解釋器中,而實際上是安裝到另一個Python解釋器中的人。這種不可估量的次數也適用於當人們破壞了他們的系統,或者想知道為什麼他們不能安裝一些與他們之前為其他項目安裝的其他東西相衝突的東西,等等,因為他們沒有不怕麻煩地在他們的本地機器上設置一個環境。
因此,為了您和我的理智,請使用python -m pip並始終嘗試使用虛擬環境。
英文原文:https://snarky.ca/why-you-should-use-python-m-pip/