Linux手動安裝新版本Python教程(CentOS)


一、說明

1.1 linux為什么不升級python版本

2008年python3就發布了,到2020年1月1日python2.7就停止更新了,為什么主流的linux遲遲不去除python2自帶python3。

我們經常聽說服務器版操作系統為了保證穩定性,對於軟件一般都只采用經過時間檢驗的穩定版本,而不采用最新版本。linux不升級python版本是否也是這個原因呢?

這確實是python2和python3都不使用最新版本的主要原因,但並不是linux遲遲不去除python2自帶python3的主要原因。

python2不升級成python3的主要原因是linux系統本身的一些軟件是python2所寫,在這些軟件沒改造成python3前都不能去掉python2,強行卸載python2會導致系統崩潰。

比如典型的,yum就是一個python腳本,當使用yum remove python2要卸載python2最終會要卸載yum,而yum受保護在不使用-f情況下是不能卸載的(Error: Trying to remove "yum", which is protected)。

或者我們換句話說,linux自帶的python首先的目地並不是給用戶用的,而是給自己的系統工具用的。

系統工具並沒有最新版本的需求沒有python3的需求系統就不裝,這就很好理解了。而且反過來,我去升級、改動系統自帶的python版本、環境的行為是不受鼓勵的,這可能會影響系統的正常運行。

 

 

1.2 當我們升級python版本時我們需要關心的問題

一方面系統自帶的python並不是為我們用戶設計的,另一方面我們需要新版本的python提供的新特性,所以此時我們就有手動安裝python的需要。

這里說的手動安裝,並不是直接的yum安裝,一方面發布到yum源上的版本基本都驗證兼容系統上的工具,另一方面發布到yum源上的版本一般都不會是最新。

這里說的手動安裝,是手動編譯安裝。當然並不是手動安裝有多難,而是我們知道yum安裝python並不會引入新的python環境而是直接覆蓋當前的python環境,而手動編譯安裝由於前面說的不應改動系統現有python環境所以要安裝到另外的目錄去,亦即會引入新的python環境。

此時我們要關心兩個問題:一是新安裝的python會不會影響已有python,二是新安裝的python使用時會不會受已有python的影響。

這兩個問題從使用角度提出的問題又可以轉化為這兩個技術角度的問題:一是python程序中import包時從哪些目錄import,二是pip安裝包時會把包安裝到哪個目錄。

 

二、python手動編譯安裝過程

下載地址:https://www.python.org/downloads/

# 以python 3.8,安裝到/data/home/opt1/python38為例
# /data/home/opt1軟鏈接到了/opt1,所以后邊可能會混雜出現兩個目錄 # 和常規的編譯安裝過程一樣 # 解壓
tar -zxf Python-3.8.0.tgz # 進入目錄 cd Python-3.8.0 # 預編譯 ./configure --prefix=/data/home/opt1/python38 # 編譯 make # 將編譯結果復制到/opt1/python38 make install

 安裝完成后,當前兩級目錄如下:

 

三、關心問題的解答

3.1 python程序中import包時從哪些目錄import

python程序中import包時從sys.path指向的那些目錄下import。

默認情況下sys.path[0]是當前被運行python文件所處的目錄(當沒有被執行文件時為空),其他是當前所使用python命令的../lib/預設置的文件(夾)。

對於用戶而言有兩個辦法修改sys.path,一種方法是python會將環境變量PYTHONPATH(冒號分隔)解析加到sys.path,所以要加入的目錄直接在~/.bashrc等文件中賦給PYTHONPATH即可。另外一種方法是sys.path本質就是一個列表,所以可以直接在python代碼中使用sys.path.insert()、sys.path.append()進行添加。

 

3.2 pip安裝包時會把包安裝到哪個目錄

在相當長一段時間內,當操作系統同時存在python2和python3時,我知道使用pip安裝python2的庫使用pip3安裝python3的庫。但同時存在兩個python3時不知道怎樣指示pip給自己想要的python安裝庫。直到幾個月前前領導說可以這么安裝:

# 假設系統現在有python36和python38兩個python3版本

# 給python36安裝faker庫
python36 -m pip install faker

# 給python36安裝faker庫
python38 -m pip install faker

這確實是安裝python庫的一個解決方案,但這並沒有正面回答 “pip安裝包時會把包安裝到哪個目錄”這個問題,所以並不令人足夠滿意。同時我一直比較疑惑:為什么"python -m pip"和直接運行pip效果是一樣的。直到直接查看pip文件內容后,這些問題都豁然開朗。

pip並不是一個二進制文件,而是一個python腳本;pip開頭使用“#!”指示了運行該文件使用的解析器;"python -m pip"和直接運行pip最終都是執行pip包下的main函數,他們本質就是一個東西所以效果肯定也一樣。

所以最終的結論是:pip把包安裝到運行pip的解析器(pythonx.y)的"../lib/pythonx.y/site-packages"目錄下;雖然未驗證,但基本可以斷定更本質是pip把包安裝在其同級目錄下,而pip的來源又取決於sys.path。

 

3.3 直接回答新舊版本python是否存在相互影響

經前邊的分析可知,導入包和安裝包都取決於sys.path而sys.path由python解析器自己決定,所以新舊版本python(在沒有發生文件覆蓋的情況下)不會相互影響。

更簡單直白點,只要你用的python命令是你想要用的那個版本,import庫和pip安裝庫都不會有問題。

 

四、虛擬環境

4.1 創建和使用虛擬環境

所有項目都使用一下python環境,會出現兩個問題,一是久了就分不清哪些庫是哪個項目所需要的不好整理依賴關系,二是不同項目可能依賴相同庫的不同版本產生沖突。

所以當前主的做法是推薦不同的項目都使用一個獨立的虛擬環境。

# 創建虛擬環境
# 含義:python3調用venv模塊,創建一個名叫test_env的虛擬環境
# 本質上是把python38文件夾復制一份到當前目錄下,並重命名為test_env
# 並不需要絕對路徑,只是我這python38沒加入環境,所以使用絕對路徑
# 創建的虛擬環境默認是在當前執行創建命令的目錄下
/opt1/python38/bin/python3 -m venv test_env

# 使用新建的虛擬環境
source test_env/bin/activate

# 退出上邊激活的虛擬環境
# 本質是test_env/bin/activate中的deactivate方法
deactivate

# 刪除虛擬環境
# 畢竟只是創建了個文件夾,所以要刪創建的虛擬環境,直接把整個文件夾刪除即可
rm -rf test_env

 

4.2 使用虛擬環境時到底修改了什么

在上邊創建虛擬環境的截圖中我們可以看到,激活之后發生了兩個變化:python變成了虛擬環境的python,命令行前也多了虛擬環境的名稱。

這兩個變化是如何實現的呢,即然是"source test_env/bin/activate"會發生的,我們直接看test_env/bin/activate文件中做了什么即可。+

可以看到主要做了兩件事,一是修改PATH變量把當前虛擬環境bin目錄加到PATH變量的最前面,這就確保使用的python是虛擬環境中的python。

二是修改PS1變量把虛擬環境的名稱加到PS1變量前面,這就實現了命令行前多了虛擬環境的名稱。(使用conda時其效果與此類似,實現方法也是一樣的)

再回頭看deactivate,主要做的主要是與activate相反的兩件事:還原PATH變量,還原PS1變量。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM