我遇到了一個問題,我試圖在虛擬環境中運行 Django 應用程式,但它一直向我顯示有關缺少需要安裝的軟體包的錯誤,盡管我之前確實使用pip install <package-name>.
直到我用來python -m pip install <package-name>安裝丟失的軟體包后,這些問題才能得到解決。
我的問題是這兩個命令有什么區別?其中一個命令是否將軟體包安裝到虛擬環境,另一個是全域安裝?我糊涂了。
旁注:運行時pip freeze顯示的已安裝軟體包與我運行時顯示的不同python -m pip freeze。
更新:
運行pip list -v顯示使用安裝的包pip install <package-name>位于虛擬環境中的lib/python3.8/site-packages目錄下,運行python -m pip list -v顯示使用安裝的包python -m pip <package-name>位于/usr/lib/<python3 or python3.8>/<site-packages or dist-packages>目錄下。
uj5u.com熱心網友回復:
通常沒有區別。
該python -m標志允許您運行特定模塊。例如,您可以運行python -m http.server以在當前目錄中啟動一個簡單的服務器。
Python 包含一個“腳本”目錄。根據您的系統設定,scripts目錄中的模塊可以直接從 shell 運行而無需python -m前綴。例如,通常您black直接從 shell運行。
但是,您可能不想信任直接從 shell 運行 python 模塊的原因有多種,包括:
- 運行特定的 python 版本。您可以
py -3.6 -m pip install something指定python版本 - 無論出于何種原因,您都不想將腳本檔案夾添加到 PATH 中。可能是因為某些名稱與您計算機上的其他程式沖突。
在 virtualenv 中,這兩個命令通常會做同樣的事情,因為它們virtualenv會正確設定你的 PATH
uj5u.com熱心網友回復:
歡迎來到符號鏈接、二進制可發現性PATH和 shebang #!/...(*nix) 的世界。
在深入了解這一切之前,讓我們先談談什么pip是:
pip既是一個 python 模塊(即python -m pip(-m平均模塊))又是一個二進制$ pip. pip由于二進制檔案(程式)是可選的,因此不是必需的。pip因為模塊(在site-packages安裝所有 python 模塊的地方)是絕對需要的!沒有它什么都不會作業,或者更糟糕的是,你會使用pip你安裝的另一個python版本的模塊,然后你真的會用頭撞墻......
路徑變數
echo $PATH (*nix) 會顯示如下內容:
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
這意味著,該系統通過終端將尋找二進制第一內側/usr/local/bin再/usr/bin然后......等等。如果它首先找到它,那就太好了,它已經完成,無需繼續尋找。你可以在不同的目錄中使用相同的二進制名稱,順序PATH很重要,第二個永遠不會被執行,永遠。
我為什么要提到這個?好吧,假設您安裝了多個版本的pythonor pip,并且將其安裝在錯誤的位置?順序錯在哪里?那個二進制檔案不會按預期運行。
符號鏈接
您可以擁有不同版本的pipand python-- 它們彼此獨立,這意味著僅僅因為您使用的python是 3.8 版,并不意味著您pip指向同一個 python 二進制檔案。
一種快速檢查方法是:(這適用于pip)
$ ls -ls $(which python)
0 lrwxr-xr-x 1 root wheel 75 Jan 1 2020 /usr/bin/python -> ../../System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7
您可以看到它使用的是系統版本,python如果我只是運行python,我的任何其他版本都將被忽略,我可以通過指定版本號來“修復”這個問題,例如python3.8......
您可以通過首先弄清楚您可以使用哪些二進制檔案來解決這個問題:
$ echo $PATH | sed 's/:/ /g' | xargs -n1 -I{} find {} -name 'python*' | grep -v 'config$'
/usr/local/bin/python3
/usr/local/bin/python3.9
/usr/local/bin/python3.8
/usr/bin/python3
/usr/bin/python
/usr/bin/python2
/usr/bin/pythonw
/usr/bin/pythonw2.7
/usr/bin/python2.7
假設我希望我的默認python值為python3.8,然后執行以下操作:
$ ln -s /usr/local/bin/python3.8 /usr/local/bin/python
$ hash -r
hash -r 告訴終端忘記它之前找到的所有banaries,否則你的新符號鏈接將不起作用
問:為什么不直接覆寫它?
The astute among you might ask, if the default python is inside /usr/bin/python why not just override it using?
$ ln -sf /usr/local/bin/python3.8 /usr/bin/python
/usr/bin/ is protected, and it's bad form to mess around with system prefernces. It's best not to touch it, /usr/local/bin is yours (the user of the machine) to mess with.
Shebang #!/...
For the most part you will find the pip binary file (thats just plain text by the way) to start like this:
#!/usr/bin/env python
or
#!/usr/local/bin/python3.9
This says, i'm a text file that needs to be ran with the following executable. In the first example, it's using the system to fin the binary python the same way you would find it in the terminal, see PATH variable above. The second example is a direct path to the binary for the system to use.
Remember pip is a module, the binary pip literaly says this: (this is slighly modified to make it as basic as possible and illustrate a point)
#!/usr/bin/env python
import sys
from pip._internal.cli.main import main
sys.exit(main())
- use the
pythonbinary - import the
sysmodule to be used later... - import the
mainfunction from thepipmodule - run
main, what ever code it returns pass it tosys.exit(..)usually will return0but thats neighter here nor there.. just an FYI
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/338193.html
