# `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` for UNIX-style paths

- `ntpath` for Windows paths

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

os.path.abspath(path)

  Return a normalized absolutized version of the pathname path. On most platforms, this is equivalent to calling `normpath(join(os.getcwd(), path))`.

  也參考

  `os.path.join()` and `os.path.normpath()`.

  在 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()` 不同，此函式回傳的是有效路徑。

  在 3.5 版被加入.

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

  在 3.13 版的變更: Any iterable can now be passed, rather than just sequences.

os.path.commonprefix(list, /)

  Return the longest string prefix (taken character-by-character) that is a prefix of all strings in list. If list is empty, return the empty string (`''`).

  警告

  This function may return invalid paths because it works a character at a time. If you need a common path prefix, then the algorithm implemented in this function is not secure. Use `commonpath()` for finding a common path prefix.

      >>> 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 上，表示這是以兩個（反）斜線開頭或者以一個驅動機字母、冒號和（反）斜線開頭。

  也參考

  `abspath()`

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

  在 3.13 版的變更: On Windows, returns `False` if the given path starts with exactly one (back)slash.

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`。

  在 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)。在 Linux 系統上，即使它們不是掛載點，也會始終回傳 `True` 給 btrfs 子卷（subvolumes）。在 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 驅動機的資訊。

  在 3.12 版被加入.

  在 3.13 版的變更: The function is now available on all platforms, and will always return `False` on those that have no support for Dev Drives

os.path.isreserved(path)

  Return `True` if path is a reserved pathname on the current system.

  On Windows, reserved filenames include those that end with a space or dot; those that contain colons (i.e. file streams such as "name:stream"), wildcard characters (i.e. `'*?"<>'`), pipe, or ASCII control characters; as well as DOS device names such as "NUL", "CON", "CONIN$", "CONOUT$", "AUX", "PRN", "COM1", and "LPT1".

  備註

  This function approximates rules for reserved paths on most Windows systems. These rules change over time in various Windows releases. This function may be updated in future Python releases as changes to the rules become broadly available.

  可用性: Windows.

  在 3.13 版被加入.

os.path.join(path, /, *paths)

  Join one or more path segments intelligently. The return value is the concatenation of path and all members of *paths, with exactly one directory separator following each non-empty part, except the last. That is, the result will only end in a separator if the last part is either empty or ends in a separator.

  If a segment is an absolute path (which on Windows requires both a drive and a root), then all previous segments are ignored and joining continues from the absolute path segment. On Linux, for example:

      >>> os.path.join('/home/foo', 'bar')
      '/home/foo/bar'
      >>> os.path.join('/home/foo', '/home/bar')
      '/home/bar'

  On Windows, the drive is not reset when a rooted path segment (e.g., `r'\foo'`) is encountered. If a segment is on a different drive or is an absolute path, all previous segments are ignored and the drive is reset. For example:

      >>> os.path.join('c:\\', 'foo')
      'c:\\foo'
      >>> os.path.join('c:\\foo', 'd:\\bar')
      'd:\\bar'

  Note that since there is a current directory for each drive, `os.path.join("c:", "foo")` represents a path relative to the current directory on drive `C:` (`c:foo`), not `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)

  回傳指定檔案名稱的規範路徑，會消除路徑中遇到的所有符號連結（如果作業系統支援）。在 Windows 上，此函式還會解析 MS-DOS（也稱為 8.3）樣式的名稱，例如 `C:\\PROGRA~1` 會被解析為 `C:\\Program Files`。

  By default, the path is evaluated up to the first component that does not exist, is a symlink loop, or whose evaluation raises `OSError`. All such components are appended unchanged to the existing part of the path.

  Some errors that are handled this way include "access denied", "not a directory", or "bad argument to internal function". Thus, the resulting path may be missing or inaccessible, may still contain links or loops, and may traverse non-directories.

  This behavior can be modified by keyword arguments:

  If strict is `True`, the first error encountered when evaluating the path is re-raised. In particular, `FileNotFoundError` is raised if path does not exist, or another `OSError` if it is otherwise inaccessible.

  If strict is `os.path.ALLOW_MISSING`, errors other than `FileNotFoundError` are re-raised (as with `strict=True`). Thus, the returned path will not contain any symbolic links, but the named file and some of its parent directories may be missing.

  備註

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

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

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

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

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

  在 3.13.4 版的變更: The `ALLOW_MISSING` value for the strict parameter was added.

os.path.ALLOW_MISSING

  Special value used for the strict argument in `realpath()`.

  在 3.13.4 版被加入.

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 的支援。

os.path.split(path, /)

  Split the pathname path into a pair, `(head, tail)` where tail is the last pathname component and head is everything leading up to that. The tail part will never contain a slash; if path ends in a slash, tail will be empty. If there is no slash in path, head will be empty. If path is empty, both head and tail are empty. Trailing slashes are stripped from head unless it is the root (one or more slashes only). In all cases, `join(head, tail)` returns a path to the same location as path (but the strings may differ). Also see the functions `join()`, `dirname()` and `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')

  在 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`。