HOWTO · Python
Python 中的相對路徑
了解 Python 絕對路徑與相對路徑的運作方式、其基準目錄如何影響解析,以及如何使用標準函式庫建構路徑。
本頁內容
相對路徑會以某個基準目錄來解析,通常是程序目前的工作目錄。它不會自動表示相對於 Python 指令碼所在位置的路徑。若路徑不應受該基準影響,請使用絕對路徑;也可以選擇基準目錄,再據此組合相對路徑。
Python 中的檔案路徑
檔案路徑由目錄名稱和檔名組成。例如,C:\\PythonProjects\\Tutorials\\Paths\\paths.py 表示位於 C: 磁碟機下的指令碼。Windows 路徑通常以反斜線(\\)顯示,而 macOS 和 Linux 路徑通常以正斜線(/)顯示。這些是檔案系統的分隔符;在 Python 字串常值中,反斜線也可能用來表示跳脫字元。撰寫 Windows 路徑常值時,可使用原始字串或正斜線;也可以透過 os.path.join() 組合路徑,讓 Python 選擇目前平台適用的分隔符。
以下範例使用這種目錄結構:Tutorials 底下有兩個同層目錄 Paths 和 Strings;paths.py 位於 Paths,而 string.py 位於 Strings。
Windows、Mac 和 Linux 的差異
Windows 路徑可能會顯示為 C:\\PythonProjects\\Tutorials\\Paths\\paths.py,POSIX 路徑則可能是 /home/ava/Tutorials/Paths/paths.py。兩者的分隔符不同,但 Python 的路徑工具會處理各平台適用的格式。以 Python 字串表示路徑時,也必須遵守 Python 的字串常值規則,因此建議使用 r"C:\\PythonProjects\\Tutorials"、"C:/PythonProjects/Tutorials",或將路徑元件傳給 os.path.join()。
目前工作目錄
目前工作目錄(cwd)屬於正在執行的程序,而不是某個特定檔案。os.getcwd() 會傳回該目錄。像 Strings/string.py 這樣的相對路徑會以 cwd 為基準解析;變更 cwd 後,同一個相對路徑的解析位置也會改變。os.chdir() 會變更整個程序的 cwd,因此可能影響程序中的其他程式碼。對指令碼和應用程式而言,明確指定基準通常比變更 cwd 更容易理解與維護。
絕對路徑
絕對路徑會從檔案系統根目錄(Windows 上則是磁碟機)指出位置。對於正在執行的指令碼,若 __file__ 可用(從檔案執行指令碼時通常如此),os.path.abspath(__file__) 會產生指令碼路徑的絕對形式。這和解析任意相對路徑不同:相對路徑通常以程序的 cwd 為基準解析。
例如,若 cwd 是 C:\\PythonProjects\\Tutorials,檔案 Strings\\string.py 的絕對路徑可以寫成 C:\\PythonProjects\\Tutorials\\Strings\\string.py。在該電腦上,絕對路徑能明確指出位置;不過,專案移到其他位置時,通常需要調整路徑。
在 Python 中建構 string.py 的絕對路徑
若要建構絕對路徑,請從檔案系統根目錄開始,並接上目錄名稱和檔名。os.path.abspath() 會讓結果成為目前電腦上的絕對路徑。建構路徑不會建立檔案;此範例只檢查組合出的路徑是否為絕對路徑。
import os
root = os.path.abspath(os.sep)
absolute_path = os.path.abspath(
os.path.join(root, "Tutorials", "Strings", "string.py")
)
print(os.path.isabs(absolute_path))
True
相對路徑
相對路徑會以指定的基準來指出位置。在一般 Python 程式中,基準通常是目前工作目錄,但程式也可以選擇其他目錄。必須清楚指定基準:當 cwd 是 Tutorials 時,Strings/string.py 指向的位置,和 cwd 是 Tutorials/Paths 時不同。
若 cwd 是 C:\\PythonProjects\\Tutorials,同層目錄中的檔案路徑是 Strings\\string.py。若 cwd 是 C:\\PythonProjects\\Tutorials\\Paths,則可透過 ..\\Strings\\string.py 找到同一個檔案,其中 .. 代表上一層目錄。os.path.join() 可以組合這些路徑元件,無須將分隔符寫死。若要改以指令碼所在目錄為基準解析相對路徑,可從 __file__ 推導該目錄,並將它明確用作基準;如此一來,不論程式從哪個目錄啟動,都能找到與程式碼放在一起的資源。
例如,先從指令碼所在目錄往上一層到其父目錄(Tutorials),再接上 Strings 和 string.py。這樣建構出的路徑會以指令碼位置為基準,而不是以程序 cwd 為基準。os.path.abspath() 可以將結果轉換為絕對形式。此範例假設 Paths 和 Strings 是同層目錄;若專案結構不同,請相應調整路徑元件。
在 Python 中建構從 Paths 到 Strings 的相對路徑
若要表示從 Tutorials/Paths 到 Tutorials/Strings/string.py 的路徑,請將這兩個位置傳給 os.path.relpath()。start 引數會明確指定以 Paths 為基準,因此在此目錄結構中,得到的相對路徑是 ../Strings/string.py。這只會根據提供的名稱計算路徑字串;它不會變更程序 cwd、不會檢查目的地是否存在,也不會存取該檔案。若以不同基準解析這個結果,所指位置也會不同。
此範例使用代表共用目錄結構的相對名稱。os.path.relpath() 會以字串方式比較路徑,因此計算時不要求目錄或檔案實際存在。
import os
paths = os.path.join("Tutorials", "Paths")
string_file = os.path.join("Tutorials", "Strings", "string.py")
relative_path = os.path.relpath(string_file, start=paths)
print(relative_path.replace(os.sep, "/"))
若要變更程序的 cwd,請參閱 os.chdir()。若要查看程序的 cwd,請參閱 os.getcwd()。