# `os.path` --- 常見的路徑名操作

原始碼： Lib/genericpath.py、Lib/posixpath.py (用於 POSIX 系統) 和 Lib/ntpath.py (用於 Windows).

該模組實現了一些有用的路徑名操作函式。若要讀取或寫入檔案，請參閱 `open()` 函數，要存取檔案系統，請參閱 `os` 模組。路徑參數可以以字串、位元組或任何依照 `os.PathLike` 協議實作的物件傳遞。

與 Unix shell 不同，Python 不會自動進行路徑展開 (path expansions)。當應用程式需要進行類似 shell 的路徑展開時，可以明確地呼叫 `expanduser()` 和 `expandvars()` 等函式。（另請參閱 `glob` 模組。）

也參考

`pathlib` 模組提供了高階的路徑物件。

備註

所有這些函數都只接受位元組或字串物件作為參數。如果回傳的是路徑或檔案名稱，結果將是相同型別的物件。

備註

由於不同的作業系統具有不同的路徑命名慣例，在標準函式庫中的路徑模組有數個版本可供使用，而 `os.path` 模組都會是運行 Python 之作業系統所適用本地路徑。然而，如果你想要操作始終以某個不同於本機格式表示的路徑，你也可以引入並使用對應的模組。它們都具有相同的介面：

- `posixpath` 用於 UNIX 形式的路徑

- `ntpath` 用於 Windows 的路徑

在 3.8 版的變更: 對於包含有作業系統層級無法表示之字元或位元組的路徑，`exists()`、`lexists()`、`isdir()`、`isfile()`、`islink()` 和 `ismount()` 函式現在會回傳 `False`，而不是引發例外。

os.path.abspath(path)

  回傳經正規化的絕對路徑名 path 。在大多數平台上，這等效於按照以下方式呼叫 `normpath()` 函式：`normpath(join(os.getcwd(), path))`。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.basename(path)

  回傳路徑名 path 的基底名稱。這是將 path 傳遞給函式 `split()` 後回傳結果中的第二個元素。請注意，此函式的結果與 Unix 的 basename 程式不同；對於 `'/foo/bar/'`，basename 回傳 `'bar'`，而 `basename()` 函式回傳空字串（`''`）。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.commonpath(paths)

  回傳序列 paths 中每個路徑名的最長共同子路徑。如果 paths 同時包含絕對路徑和相對路徑、paths 位於不同的驅動機或 paths 為空，則引發 `ValueError`。與 `commonprefix()` 不同，此函式回傳的是有效路徑。

  Added in version 3.5.

  在 3.6 版的變更: 接受一個類路徑物件的序列。

os.path.commonprefix(list)

  回傳 list 中所有路徑的最長路徑前綴（逐字元比較）。如果 list 為空，則回傳空字串（`''`）。

  備註

  由於此函式是逐字元比較，因此可能會回傳無效的路徑。若要獲得有效的路徑，請參考 `commonpath()` 函式。

      >>> os.path.commonprefix(['/usr/lib', '/usr/local/lib'])
      '/usr/l'

      >>> os.path.commonpath(['/usr/lib', '/usr/local/lib'])
      '/usr'

  在 3.6 版的變更: 接受一個 path-like object。

os.path.dirname(path)

  回傳路徑名 path 的目錄名稱。這是將 path 傳遞給函式 `split()` 後回傳之成對結果中的第一個元素。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.exists(path)

  如果 path 是一個存在的路徑或一個開啟的檔案描述器則回傳 `True`。對於已損壞的符號連結則回傳 `False`。在某些平台上，即使 path 實際存在，如果未被授予執行 `os.stat()` 的權限，此函式仍可能回傳 `False`。

  在 3.3 版的變更: 現在 path 可以是一個整數：如果它是一個開啟的檔案描述器，則回傳 `True`；否則回傳 `False`。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.lexists(path)

  如果 path 是一個存在的路徑則回傳 `True`，對已損壞的符號連結也是。在缺乏 `os.lstat()` 的平台上，與 `exists()` 函式等效。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.expanduser(path)

  在 Unix 和 Windows 上，將引數中以 `~` 或 `~user` 開頭的部分替換為該 user 的家目錄。

  在 Unix 上，如果環境變數 `HOME` 有被設置，則將初始的 `~` 替換為該變數的值；否則將使用內建模組 `pwd` 在密碼目錄中查找當前使用者的家目錄。對於初始的 `~user`，直接在密碼目錄中查找該使用者的家目錄。

  在 Windows 上，如果 `USERPROFILE` 有被設置，則使用該變數的值；否則將結合 `HOMEPATH` 和 `HOMEDRIVE`。對於初始的 `~user`，會檢查當前使用者的家目錄的最後一個目錄元件是否與 `USERNAME` 相符，如果相符則替換它。

  如果展開失敗或路徑不以波浪符號 (tilde) 開頭，則回傳原始路徑，不做任何變更。

  在 3.6 版的變更: 接受一個 path-like object。

  在 3.8 版的變更: 在 Windows 上不再使用 `HOME` 變數。

os.path.expandvars(path)

  回傳已展開環境變數的引數。形如 `$name` 或 `${name}` 的子字串會被替換為環境變數 name 的值。無效的變數名稱和對不存在變數的引用保持不變。

  在 Windows 上，除了支援 `$name` 和 `${name}` 形式的展開外，還支援 `%name%` 形式的展開。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.getatime(path)

  回傳 path 的最後存取時間。回傳值是一個浮點數，表示自紀元（參見 `time` 模組）以來的秒數。如果檔案不存在或無法存取，則引發 `OSError`。

os.path.getmtime(path)

  回傳 path 的最後修改時間。回傳值是一個浮點數，表示自紀元（參見 `time` 模組）以來的秒數。如果檔案不存在或無法存取，則引發 `OSError`。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.getctime(path)

  回傳系統的 ctime。在某些系統（如 Unix）上，這是最後一次元數據 (metadata) 更改的時間，在其他系統（如 Windows）上則是 path 的建立時間。回傳值是一個浮點數，表示自紀元（參見 `time` 模組）以來的秒數。如果檔案不存在或無法存取），則引發 `OSError`。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.getsize(path)

  回傳 path 的大小（以位元組為單位）。如果檔案不存在或無法存取，則引發 `OSError`。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.isabs(path)

  如果 path 是絕對路徑名，則回傳 `True`。在 Unix 上，這表示它以斜線開頭；在 Windows 上，表示在去除可能的驅動機字母後，以（反）斜線開頭。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.isfile(path)

  如果 path 是一個`已存在的`常規檔案，則回傳 `True`。這將跟隨符號連結，因此同一個路徑可以同時回傳 `islink()` 和 `isfile()` 的結果為真。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.isdir(path)

  如果 path 是一個`已存在的`目錄，則回傳 `True`。這將跟隨符號連結，因此同一個路徑可以同時回傳 `islink()` 和 `isfile()` 的結果為真。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.isjunction(path)

  如果 path 是指向`已存在的`目錄條目且為聯接點 (junction)，則回傳 `True`。如果目前平台不支援聯接點，則始終返回 `False`。

  Added in version 3.12.

os.path.islink(path)

  如果 path 是指向`已存在的`目錄項目且為符號連結，則回傳 `True`。如果 Python 執行時不支援符號連結，則始終回傳 `False`。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.ismount(path)

  如果路徑名 path 是一個掛載點 (mount point)，則回傳 `True`：即在檔案系統中掛載了不同的檔案系統。在 POSIX 系統上，該函式檢查 path 的父目錄 `path/..` 是否位於不同的設備上，或者 `path/..` 和 path 是否指向同一設備上的相同 i-node --- 這應該能夠檢測出所有 Unix 和 POSIX 變體的掛載點。但無法可靠地檢測出相同檔案系統上的綁定掛載點 (bind mount)。在 Windows 上，以驅動機字母開頭的根目錄和 UNC 共享路徑始終是掛載點，對於任何其他路徑，會呼叫 `GetVolumePathName` 函式來檢查它是否與輸入路徑不同。

  在 3.4 版的變更: 新增在 Windows 上檢測非根目錄掛載點的支援。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.isdevdrive(path)

  如果路徑名 path 位於 Windows Dev 驅動機上，則回傳 `True`。Dev 驅動機針對開發人員場景進行了優化，提供更快的讀寫檔案性能。建議將其用於原始程式碼、臨時建置目錄、封包快取和其他 I/O 密集型操作。

  可能會對無效的路徑引發錯誤，例如，沒有可識別的驅動機的路徑，但在不支援 Dev 磁碟機的平台上返回 `False`。請參閱 Windows 文件以了解有關啟用和建立 Dev 驅動機的資訊。

  適用：Windows。

  Added in version 3.12.

os.path.join(path, *paths)

  聰明地連接一個或多個路徑段。回傳值是 path 和 *paths 的所有成員的串聯，每個非空部分後面都有一個目錄分隔符號，除了最後一個部分。換句話說，如果最後一個部分為空或以分隔符號結尾，結果只會以分隔符號結尾。如果一個段是絕對路徑（在 Windows 上需要驅動機和根），則忽略所有之前的段，並從絕對路徑段繼續連接。

  在 Windows 上，當遇到根路徑段（例如，`r'\foo'`）時，驅動機不會被重置。如果一個段位於不同的驅動機上，或者是絕對路徑，則將忽略所有之前的段並重置驅動機。請注意，由於每個驅動機都有當前目錄，`os.path.join("c:", "foo")` 表示相對於驅動機 `C:` 的當前目錄的路徑（即 `c:foo`），而不是 `c:\foo`。

  在 3.6 版的變更: path 和 paths 接受 path-like object 作為參數。

os.path.normcase(path)

  將路徑名的大小寫規範化。在 Windows 上，將路徑名中的所有字元轉換為小寫，並將正斜線轉換為反斜線。在其他作業系統上，回傳原始路徑。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.normpath(path)

  > 通過合併多餘的分隔符號和上層引用來標準化路徑名，使得 `A//B`、`A/B/`、`A/./B` 和 `A/foo/../B` 都變成 `A/B`。這種字串操作可能會改變包含符號連結的路徑的含義。在 Windows 上，它將正斜線轉換為反斜線。要標準化大小寫，請使用 `normcase()`。

  備註

  > 在 POSIX 系統中，根據 IEEE Std 1003.1 2013 版; 4.13 Pathname Resolution 標準，如果一個路徑名恰好以兩個斜線開頭，則在前導字元後的第一個部分可能會以由實作品自行定義的方式解釋，雖然多於兩個前導字元應該被視為單個字元。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.realpath(path, *, strict=False)

  回傳指定檔案名稱的規範路徑，消除路徑中遇到的所有符號連結（如果作業系統支援）。

  如果路徑不存在或遇到符號連結迴圈，且 strict 為 `True`，則引發 `OSError`。如果 strict 為 `False`，則將路徑盡可能解析，並將任何剩餘部分附加在後面，而不檢查其是否存在。

  備註

  此函式模擬作業系統使路徑成為規範的過程，Windows 和 UNIX 之間在鏈接和後續路徑部份交互方式方面略有不同。

  作業系統的 API 會根據需要自動使路徑正則，因此通常不需要呼叫此函式。

  在 3.6 版的變更: 接受一個 path-like object。

  在 3.8 版的變更: 在 Windows 上，現在會解析符號連結和連接點。

  在 3.10 版的變更: 新增 strict 參數。

os.path.relpath(path, start=os.curdir)

  從當前目錄或可選的 start 目錄回傳到 path 的相對檔案路徑。這是一個路徑計算：不會訪問檔案系統來確認 path 或 start 的存在或屬性。在 Windows 上，當 path 和 start 在不同的驅動機上時，會引發 `ValueError`。

  start 的預設值為 `os.curdir`。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.samefile(path1, path2)

  如果兩個路徑名引數指向同一個檔案或目錄，則回傳 `True`。這是通過設備編號和 i-node 編號來確定的，如果對任一路徑名的 `os.stat()` 呼叫失敗，則會引發異常。

  在 3.2 版的變更: 新增對 Windows 的支援。

  在 3.4 版的變更: 現在在 Windows 上使用與其他所有平台相同的實作方式。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.sameopenfile(fp1, fp2)

  如果文件描述符 fp1 和 fp2 指向同一個檔案，則回傳 `True`。

  在 3.2 版的變更: 新增對 Windows 的支援。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.samestat(stat1, stat2)

  如果 stat 值組 stat1 和 stat2 指向同一個檔案，則回傳 `True`。這些結構可能由 `os.fstat()`、`os.lstat()` 或 `os.stat()` 回傳。此函式使用 `samefile()` 和 `sameopenfile()` 實現了底層比較。

  在 3.4 版的變更: 新增對 Windows 的支援。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.split(path)

  將路徑名 path 拆分為 `(head, tail)` 一對，其中 tail 是最後一個路徑名部份，head 是在它之前的所有部分。tail 部分不會包含斜線；如果 path 以斜線結尾，則 tail 將為空。如果 path 中沒有斜線，則 head 將為空。如果 path 為空，則 head 和 tail 都為空。除非 head 是根目錄（僅有一個或多個斜線），否則從 head 中刪除尾部的斜線。在所有情況下，`join(head, tail)` 回傳指向與 path 相同位置的路徑（但字串可能不同）。還可以參考函式 `dirname()` 和 `basename()`。

  在 3.6 版的變更: 接受一個 path-like object。

os.path.splitdrive(path)

  將路徑名 path 拆分為 `(drive, tail)` 一對，其中 drive 是掛載點或空字串。在不使用驅動機規範的系統上，drive 將始終為空字串。在所有情況下，`drive + tail` 將與 path 相同。

  在 Windows 上，將路徑名拆分為驅動機或 UNC 共享點以及相對路徑。

  如果路徑包含驅動機字母，則 drive 將包含從頭到冒號（包括冒號）的所有內容：

      >>> splitdrive("c:/dir")
      ("c:", "/dir")

  如果路徑包含 UNC 路徑，則驅動機將包含主機名和共享名：

      >>> splitdrive("//host/computer/dir")
      ("//host/computer", "/dir")

  在 3.6 版的變更: 接受一個 path-like object。

os.path.splitroot(path)

  將路徑名 path 拆分為一個 3 項值組 `(drive, root, tail)`，其中 drive 是設備名稱或掛載點，root 是驅動機後的分隔符字串，tail 是在根後的所有內容。這些項目中的任何一個都可能是空字串。在所有情況下，`drive + root + tail` 將與 path 相同。

  在 POSIX 系統上，drive 始終為空。root 可能為空（如果 path 是相對路徑），一個斜線（如果 path 是絕對路徑），或者兩個斜線（根據 IEEE Std 1003.1-2017; 4.13 Pathname Resolution 的實作定義）。例如：

      >>> splitroot('/home/sam')
      ('', '/', 'home/sam')
      >>> splitroot('//home/sam')
      ('', '//', 'home/sam')
      >>> splitroot('///home/sam')
      ('', '/', '//home/sam')

  在 Windows 上，drive 可能為空、驅動機名稱、UNC 共享或設備名稱。root 可能為空，斜線或反斜線。例如：

      >>> splitroot('C:/Users/Sam')
      ('C:', '/', 'Users/Sam')
      >>> splitroot('//Server/Share/Users/Sam')
      ('//Server/Share', '/', 'Users/Sam')

  Added in version 3.12.

os.path.splitext(path)

  將路徑名 path 拆分為一對 `(root, ext)`，使得 `root + ext == path`，且副檔名 ext 為空或以點開頭且最多包含一個點 (period)。

  如果路徑不包含副檔名，則 ext 將為 `''`：

      >>> splitext('bar')
      ('bar', '')

  如果路徑包含副檔名，則 ext 將設置為該副檔名，包括前導的點。請注意，前面的點將被忽略：

      >>> splitext('foo.bar.exe')
      ('foo.bar', '.exe')
      >>> splitext('/foo/bar.exe')
      ('/foo/bar', '.exe')

  路徑的最後一個部份的前導點被認為是根的一部分：

      >>> splitext('.cshrc')
      ('.cshrc', '')
      >>> splitext('/foo/....jpg')
      ('/foo/....jpg', '')

  在 3.6 版的變更: 接受一個 path-like object。

os.path.supports_unicode_filenames

  如果可以使用任意的 Unicode 字串作為檔案名（在檔案系統所施加的限制範圍內），則回傳 `True`。