模組路徑

May 6, 2022

在〈簡介模組〉談過 sys.path,這個清單中列出了尋找模組時的路徑。

sys.path

清單內容基本上可來自於幾個來源:

  • 執行 python 直譯器時的資料夾
  • PYTHONPATH 環境變數
  • Python 安裝中標準程式庫等資料夾
  • PTH 檔案列出的資料夾

如果想動態地管理模組的尋找路徑,也可以透過程式變更 sys.path 的內容來達到。例如在沒有對 PYTHONPATH 設定任何資訊的情況下,在進入 REPL 後,可以如下進行設定:

>>> import sys
>>> sys.path.append('c:\\workspace')

PTH 檔案

可以在一個 .pth 檔案列出模組搜尋路徑,一行一個路徑。例如:

C:\workspace\libs
C:\workspace\third-party
C:\workspace\devs 

PTH 檔案的存放位置,不同作業系統並不相同,可以透過 site 模組的 getsitepackages 函式取得位置,以 Windows 的 Python 安裝版本為例,會顯示以下的位置:

>>> import site
>>> site.getsitepackages()
['C:\\Winware\\Python310', 'C:\\Winware\\Python310\\lib\\site-packages']
>>>

如果確實建立了 workspace.pth 中列出的資料夾,而且將 workspace.pth 放置到 C:\Winware\Python310,那麼 sys.path 就會是以下的結果:

>>> import sys
>>> sys.path
['', 'C:\\Winware\\Python310\\Python310.zip', 'C:\\Winware\\Python310\\DLLs', 'C:\\Winware\\Python310\\lib', 'C:\\Winware\\Python310', 'C:\\workspace\\libs', 'C:\\workspace\\third-party', 'C:\\workspace\\devs', 'C:\\Winware\\Python310\\lib\\site-packages']

如果僅在 PTH 檔案中列出路徑,卻沒有建立對應的資料夾,sys.path 不會加入那些路徑。

如果將 workspace.pth 放置到 C:\Winware\Python310\lib\site-packages,那麼 sys.path 就會是以下的結果:

>>> import sys
>>> sys.path
['', 'C:\\Winware\\Python310\\Python310.zip', 'C:\\Winware\\Python310\\DLLs', 'C:\\Winware\\Python310\\lib', 'C:\\Winware\\Python310', 'C:\\Winware\\Python310\\lib\\site-packages', 'C:\\workspace\\libs', 'C:\\workspace\\third-party', 'C:\\workspace\\devs']

如果想將 PTH 檔案放置到其他資料夾,可以使用 site.addsitedir 函式新增 PTH 檔案的資料夾來源,例如,可以將 workspace.pth 放置到 C:\workspace,接著如下操作:

>>> import site
>>> site.addsitedir('C:\workspace')
>>> import sys
>>> sys.path
['', 'C:\\Winware\\Python310\\Python310.zip', 'C:\\Winware\\Python310\\DLLs', 'C:\\Winware\\Python310\\lib', 'C:\\Winware\\Python310', 'C:\\Winware\\Python310\\lib\\site-packages', 'C:\\workspace', 'C:\\workspace\\libs', 'C:\\workspace\\third-party', 'C:\\workspace\\devs']

除了 workspace.pth 列出的路徑,site.addsitedir 函式新增的路徑,也會是 sys.path 路徑中的一部份。

若有興趣瞭解細節的話,以下列出了一個模組被 import 時發生了什麼事:

  1. sys.path 尋找模組。
  2. 載入、編譯模組的程式碼。
  3. 建立空的模組物件。
  4. sys.modules 記錄該模組。
  5. 執行模組中的程式碼及相關定義。

分享到 LinkedIn 分享到 Facebook 分享到 Twitter