pathlib --- 物件導向檔案系統路徑

Added in version 3.4.

源代码: Lib/pathlib/


此模組提供代表檔案系統路徑的類別,能適用不同作業系統的語意。路徑類別分成兩種,一種是純路徑 (pure paths),提供沒有 I/O 的單純計算操作,另一種是實體路徑 (concrete paths),繼承自純路徑但也提供 IO 操作。

../_images/pathlib-inheritance.png

如果你之前從未使用過此模組或不確定哪個類別適合你的任務,那你需要的最有可能是 Path。它針對程式執行所在的平台實例化一個實體路徑

純路徑在某些特殊情境下是有用的,例如:

  1. 如果你想在 Unix 機器上處理 Windows 路徑(或反過來),你無法在 Unix 上實例化 WindowsPath,但你可以實例化 PureWindowsPath

  2. 你想確保你的程式在操作路徑的時候不會真的存取到 OS。在這個情況下,實例化其中一種純路徑類別可能是有用的,因為它們不會有任何存取 OS 的操作。

也參考

PEP 428:pathlib 模組 -- 物件導向檔案系統路徑。

也參考

針對字串上的底層路徑操作,你也可以使用 os.path 模組。

基本用法

匯入主要類別:

>>> from pathlib import Path

列出子目錄:

>>> p = Path('.')
>>> [x for x in p.iterdir() if x.is_dir()]
[PosixPath('.hg'), PosixPath('docs'), PosixPath('dist'),
 PosixPath('__pycache__'), PosixPath('build')]

在當前目錄樹下列出 Python 原始碼檔案:

>>> list(p.glob('**/*.py'))
[PosixPath('test_pathlib.py'), PosixPath('setup.py'),
 PosixPath('pathlib.py'), PosixPath('docs/conf.py'),
 PosixPath('build/lib/pathlib.py')]

瀏覽目錄樹內部:

>>> p = Path('/etc')
>>> q = p / 'init.d' / 'reboot'
>>> q
PosixPath('/etc/init.d/reboot')
>>> q.resolve()
PosixPath('/etc/rc.d/init.d/halt')

查詢路徑屬性:

>>> q.exists()
True
>>> q.is_dir()
False

開啟檔案:

>>> with q.open() as f: f.readline()
...
'#!/bin/bash\n'

异常

exception pathlib.UnsupportedOperation

An exception inheriting NotImplementedError that is raised when an unsupported operation is called on a path object.

Added in version 3.13.

純路徑

純路徑物件提供處理路徑的操作,實際上不會存取檔案系統。有三種方式可以存取這些類別,我們也稱之為類型 (flavours)

class pathlib.PurePath(*pathsegments)

一個通用的類別,表示系統的路徑類型(實例化時會建立一個 PurePosixPathPureWindowsPath):

>>> PurePath('setup.py')      # Running on a Unix machine
PurePosixPath('setup.py')

pathsegments 中的每個元素可以是以下的其中一種:一個表示路徑片段的字串,或一個物件,它實作了 os.PathLike 介面且其中的 __fspath__() 方法會回傳字串,就像是另一個路徑物件:

>>> PurePath('foo', 'some/path', 'bar')
PurePosixPath('foo/some/path/bar')
>>> PurePath(Path('foo'), Path('bar'))
PurePosixPath('foo/bar')

當沒有給 pathsegments 的時候,會假設是目前的目錄:

>>> PurePath()
PurePosixPath('.')

如果一個片段是絕對路徑,則所有之前的片段會被忽略(類似 os.path.join()):

>>> PurePath('/etc', '/usr', 'lib64')
PurePosixPath('/usr/lib64')
>>> PureWindowsPath('c:/Windows', 'd:bar')
PureWindowsPath('d:bar')

在 Windows 系統上,當遇到具有根目錄的相對路徑片段(例如 r'\foo')時,磁碟機 (drive) 部分不會被重置:

>>> PureWindowsPath('c:/Windows', '/Program Files')
PureWindowsPath('c:/Program Files')

不必要的斜線和單點會被合併,但雙點 ('..') 和前置的雙斜線 ('//') 不會被合併,因為這樣會因為各種原因改變路徑的意義(例如符號連結 (symbolic links)、UNC 路徑):

>>> PurePath('foo//bar')
PurePosixPath('foo/bar')
>>> PurePath('//foo/bar')
PurePosixPath('//foo/bar')
>>> PurePath('foo/./bar')
PurePosixPath('foo/bar')
>>> PurePath('foo/../bar')
PurePosixPath('foo/../bar')

(一個使得 PurePosixPath('foo/../bar') 等同於 PurePosixPath('bar') 的單純方法,但如果 foo 是指到另一個目錄的符號連結,就會是錯誤的。)

純路徑物件實作了 os.PathLike 介面,使得它們可以在任何接受該介面的地方使用。

在 3.6 版的變更: 新增了對於 os.PathLike 介面的支援。

class pathlib.PurePosixPath(*pathsegments)

PurePath 的一個子類別,該路徑類型表示非 Windows 檔案系統的路徑:

>>> PurePosixPath('/etc')
PurePosixPath('/etc')

pathsegments 的指定方式與 PurePath 類似。

class pathlib.PureWindowsPath(*pathsegments)

PurePath 的一個子類別,該路徑類型表示 Windows 檔案系統的路徑,包括 UNC paths

>>> PureWindowsPath('c:/Program Files/')
PureWindowsPath('c:/Program Files')
>>> PureWindowsPath('//server/share/file')
PureWindowsPath('//server/share/file')

pathsegments 的指定方式與 PurePath 類似。

不論你使用的是什麼系統,你都可以實例化這些類別,因為它們不提供任何涉及系統呼叫的操作。

通用屬性

路徑物件是不可變 (immutable) 且可雜湊 (hashable) 的。相同類型的路徑物件可以被比較和排序。這些屬性遵守該類型的大小寫語意規則:

>>> PurePosixPath('foo') == PurePosixPath('FOO')
False
>>> PureWindowsPath('foo') == PureWindowsPath('FOO')
True
>>> PureWindowsPath('FOO') in { PureWindowsPath('foo') }
True
>>> PureWindowsPath('C:') < PureWindowsPath('d:')
True

不同類型的路徑物件在比較時視為不相等且無法被排序:

>>> PureWindowsPath('foo') == PurePosixPath('foo')
False
>>> PureWindowsPath('foo') < PurePosixPath('foo')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'PureWindowsPath' and 'PurePosixPath'

運算子

斜線運算子 (slash operator) 用於建立子路徑,就像是 os.path.join() 函式一樣。如果引數是絕對路徑,則忽略前一個路徑。在 Windows 系統上,當引數是具有根目錄的相對路徑(例如,r'\foo'),磁碟機部分不會被重置:

>>> p = PurePath('/etc')
>>> p
PurePosixPath('/etc')
>>> p / 'init.d' / 'apache2'
PurePosixPath('/etc/init.d/apache2')
>>> q = PurePath('bin')
>>> '/usr' / q
PurePosixPath('/usr/bin')
>>> p / '/an_absolute_path'
PurePosixPath('/an_absolute_path')
>>> PureWindowsPath('c:/Windows', '/Program Files')
PureWindowsPath('c:/Program Files')

路徑物件可以被用在任何可以接受實作 os.PathLike 的物件的地方:

>>> import os
>>> p = PurePath('/etc')
>>> os.fspath(p)
'/etc'

路徑的字串表示是原始的檔案系統路徑本身(以原生的形式,例如在 Windows 下是反斜線),你可以將其傳入任何將檔案路徑當作字串傳入的函式:

>>> p = PurePath('/etc')
>>> str(p)
'/etc'
>>> p = PureWindowsPath('c:/Program Files')
>>> str(p)
'c:\\Program Files'

類似地,對路徑呼叫 bytes 會得到原始檔案系統路徑的 bytes 物件,就像使用 os.fsencode() 編碼過的一樣:

>>> bytes(p)
b'/etc'

備註

只建議在 Unix 下呼叫 bytes。在 Windows 裡,unicode 形式是檔案系統路徑的權威表示方式。

對個別組成的存取

可以使用下列屬性來存取路徑的個別「組成」(parts, components):

PurePath.parts

一個可存取路徑的各組成的元組:

>>> p = PurePath('/usr/bin/python3')
>>> p.parts
('/', 'usr', 'bin', 'python3')

>>> p = PureWindowsPath('c:/Program Files/PSF')
>>> p.parts
('c:\\', 'Program Files', 'PSF')

(特別注意磁碟機跟本地根目錄是如何被重新組合成一個單一組成)

方法與屬性

純路徑提供以下方法與屬性:

PurePath.parser

The implementation of the os.path module used for low-level path parsing and joining: either posixpath or ntpath.

Added in version 3.13.

PurePath.drive

若存在則為一個表示磁碟機字母 (drive letter) 或磁碟機名稱 (drive name) 的字串:

>>> PureWindowsPath('c:/Program Files/').drive
'c:'
>>> PureWindowsPath('/Program Files/').drive
''
>>> PurePosixPath('/etc').drive
''

UNC shares 也被視為磁碟機:

>>> PureWindowsPath('//host/share/foo.txt').drive
'\\\\host\\share'
PurePath.root

若存在則為一個表示(本地或全域)根目錄的字串:

>>> PureWindowsPath('c:/Program Files/').root
'\\'
>>> PureWindowsPath('c:Program Files/').root
''
>>> PurePosixPath('/etc').root
'/'

UNC shares 都會有一個根目錄:

>>> PureWindowsPath('//host/share').root
'\\'

如果路徑以超過兩個連續的斜線開頭,PurePosixPath 會合併它們:

>>> PurePosixPath('//etc').root
'//'
>>> PurePosixPath('///etc').root
'/'
>>> PurePosixPath('////etc').root
'/'

備註

此行為符合 The Open Group Base Specifications Issue 6,章節 4.11 路徑名稱解析

「以兩個連續斜線開頭的路徑名稱可以根據實作定義的方式來解讀,儘管如此,開頭超過兩個斜線應該視為單一斜線。」

PurePath.anchor

磁碟機與根目錄的結合:

>>> PureWindowsPath('c:/Program Files/').anchor
'c:\\'
>>> PureWindowsPath('c:Program Files/').anchor
'c:'
>>> PurePosixPath('/etc').anchor
'/'
>>> PureWindowsPath('//host/share').anchor
'\\\\host\\share\\'
PurePath.parents

一個不可變的序列,為路徑邏輯上的祖先 (logical ancestors) 提供存取:

>>> p = PureWindowsPath('c:/foo/bar/setup.py')
>>> p.parents[0]
PureWindowsPath('c:/foo/bar')
>>> p.parents[1]
PureWindowsPath('c:/foo')
>>> p.parents[2]
PureWindowsPath('c:/')

在 3.10 版的變更: 父序列現在支援 slices 及負的索引值。

PurePath.parent

邏輯上的父路徑:

>>> p = PurePosixPath('/a/b/c/d')
>>> p.parent
PurePosixPath('/a/b/c')

你不能越過一個 anchor 或空路徑:

>>> p = PurePosixPath('/')
>>> p.parent
PurePosixPath('/')
>>> p = PurePosixPath('.')
>>> p.parent
PurePosixPath('.')

備註

這是一個純粹字句上的 (lexical) 運算,因此會有以下行為:

>>> p = PurePosixPath('foo/..')
>>> p.parent
PurePosixPath('foo')

如果你想要沿任意的檔案系統路徑往上走,建議要先呼叫 Path.resolve() 來解析符號連結 (symlink) 及去除其中的 ”..”

PurePath.name

最後的路徑組成 (final path component) 的字串表示,不包含任何磁碟機或根目錄:

>>> PurePosixPath('my/library/setup.py').name
'setup.py'

UNC 磁碟機名稱並沒有算在內:

>>> PureWindowsPath('//some/share/setup.py').name
'setup.py'
>>> PureWindowsPath('//some/share').name
''
PurePath.suffix

The last dot-separated portion of the final component, if any:

>>> PurePosixPath('my/library/setup.py').suffix
'.py'
>>> PurePosixPath('my/library.tar.gz').suffix
'.gz'
>>> PurePosixPath('my/library').suffix
''

This is commonly called the file extension.

在 3.14 版的變更: A single dot (".") is considered a valid suffix.

PurePath.suffixes

A list of the path's suffixes, often called file extensions:

>>> PurePosixPath('my/library.tar.gar').suffixes
['.tar', '.gar']
>>> PurePosixPath('my/library.tar.gz').suffixes
['.tar', '.gz']
>>> PurePosixPath('my/library').suffixes
[]

在 3.14 版的變更: A single dot (".") is considered a valid suffix.

PurePath.stem

最後的路徑組成,不包括後綴 (suffix):

>>> PurePosixPath('my/library.tar.gz').stem
'library.tar'
>>> PurePosixPath('my/library.tar').stem
'library'
>>> PurePosixPath('my/library').stem
'library'
PurePath.as_posix()

回傳一個使用正斜線 (/) 的路徑的字串表示:

>>> p = PureWindowsPath('c:\\windows')
>>> str(p)
'c:\\windows'
>>> p.as_posix()
'c:/windows'
PurePath.is_absolute()

回傳一個路徑是否是絕對路徑。一個路徑被視為絕對路徑的條件是它同時有根目錄及(如果該系統類型允許的話)磁碟機:

>>> PurePosixPath('/a/b').is_absolute()
True
>>> PurePosixPath('a/b').is_absolute()
False

>>> PureWindowsPath('c:/a/b').is_absolute()
True
>>> PureWindowsPath('/a/b').is_absolute()
False
>>> PureWindowsPath('c:').is_absolute()
False
>>> PureWindowsPath('//some/share').is_absolute()
True
PurePath.is_relative_to(other)

回傳此路徑是否為 other 路徑的相對路徑。

>>> p = PurePath('/etc/passwd')
>>> p.is_relative_to('/etc')
True
>>> p.is_relative_to('/usr')
False

該方法是基於字串的;它既不存取檔案系統,也不特別處理 ".." 片段。以下程式碼是等效的:

>>> u = PurePath('/usr')
>>> u == p or u in p.parents
False

Added in version 3.9.

自從版本 3.12 後不推薦使用,已從版本 3.14 中移除。: 額外引數的傳入已棄用;如果有的話,它們會與 other 連接在一起。

PurePath.is_reserved()

PureWindowsPath 來說,當路徑在 Windows 下被視為保留的話會回傳 True,否則回傳 False。對 PurePosixPath 來說,總是回傳 False

在 3.13 版的變更: Windows path names that contain a colon, or end with a dot or a space, are considered reserved. UNC paths may be reserved.

自從版本 3.13 後不推薦使用,將會自版本 3.15 中移除。: This method is deprecated; use os.path.isreserved() to detect reserved paths on Windows.

PurePath.joinpath(*pathsegments)

呼叫此方法會依序結合每個所給定的 pathsegments 到路徑上:

>>> PurePosixPath('/etc').joinpath('passwd')
PurePosixPath('/etc/passwd')
>>> PurePosixPath('/etc').joinpath(PurePosixPath('passwd'))
PurePosixPath('/etc/passwd')
>>> PurePosixPath('/etc').joinpath('init.d', 'apache2')
PurePosixPath('/etc/init.d/apache2')
>>> PureWindowsPath('c:').joinpath('/Program Files')
PureWindowsPath('c:/Program Files')
PurePath.full_match(pattern, *, case_sensitive=None)

Match this path against the provided glob-style pattern. Return True if matching is successful, False otherwise. For example:

>>> PurePath('a/b.py').full_match('a/*.py')
True
>>> PurePath('a/b.py').full_match('*.py')
False
>>> PurePath('/a/b/c.py').full_match('/a/**')
True
>>> PurePath('/a/b/c.py').full_match('**/*.py')
True

也參考

Pattern language documentation.

像其它方法一樣,是否區分大小寫會遵循平台的預設行為:

>>> PurePosixPath('b.py').full_match('*.PY')
False
>>> PureWindowsPath('b.py').full_match('*.PY')
True

case_sensitive 設定成 TrueFalse 會覆蓋這個行為。

Added in version 3.13.

PurePath.match(pattern, *, case_sensitive=None)

Match this path against the provided non-recursive glob-style pattern. Return True if matching is successful, False otherwise.

This method is similar to full_match(), but empty patterns aren't allowed (ValueError is raised), the recursive wildcard "**" isn't supported (it acts like non-recursive "*"), and if a relative pattern is provided, then matching is done from the right:

>>> PurePath('a/b.py').match('*.py')
True
>>> PurePath('/a/b/c.py').match('b/*.py')
True
>>> PurePath('/a/b/c.py').match('a/*.py')
False

在 3.12 版的變更: The pattern parameter accepts a path-like object.

在 3.12 版的變更: 新增 case_sensitive 參數。

PurePath.relative_to(other, walk_up=False)

計算這個路徑相對於 other 所表示路徑的版本。如果做不到會引發 ValueError

>>> p = PurePosixPath('/etc/passwd')
>>> p.relative_to('/')
PurePosixPath('etc/passwd')
>>> p.relative_to('/etc')
PurePosixPath('passwd')
>>> p.relative_to('/usr')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "pathlib.py", line 941, in relative_to
    raise ValueError(error_message.format(str(self), str(formatted)))
ValueError: '/etc/passwd' is not in the subpath of '/usr' OR one path is relative and the other is absolute.

walk_up 是 False(預設值),路徑必須以 other 為開始。當此引數是 True,可能會加入 .. 以組成相對路徑。在其他情況下,例如路徑參考到不同的磁碟機,則會引發 ValueError

>>> p.relative_to('/usr', walk_up=True)
PurePosixPath('../etc/passwd')
>>> p.relative_to('foo', walk_up=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "pathlib.py", line 941, in relative_to
    raise ValueError(error_message.format(str(self), str(formatted)))
ValueError: '/etc/passwd' is not on the same drive as 'foo' OR one path is relative and the other is absolute.

警告

這個函式是 PurePath 的一部分且可以在字串上運作。它不會檢查或存取實際的檔案架構。這會影響到 walk_up 選項,因為它假設路徑中沒有符號連結;如果需要解析符號連結的話可以先呼叫 resolve()

在 3.12 版的變更: 加入 walk_up 參數(舊的行為和 walk_up=False 相同)。

自從版本 3.12 後不推薦使用,已從版本 3.14 中移除。: 額外位置引數的傳入已棄用;如果有的話,它們會與 other 連接在一起。

PurePath.with_name(name)

回傳一個修改 name 後的新路徑。如果原始路徑沒有名稱則引發 ValueError:

>>> p = PureWindowsPath('c:/Downloads/pathlib.tar.gz')
>>> p.with_name('setup.py')
PureWindowsPath('c:/Downloads/setup.py')
>>> p = PureWindowsPath('c:/')
>>> p.with_name('setup.py')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/antoine/cpython/default/Lib/pathlib.py", line 751, in with_name
    raise ValueError("%r has an empty name" % (self,))
ValueError: PureWindowsPath('c:/') has an empty name
PurePath.with_stem(stem)

回傳一個修改 stem 後的新路徑。如果原始路徑沒有名稱則引發 ValueError:

>>> p = PureWindowsPath('c:/Downloads/draft.txt')
>>> p.with_stem('final')
PureWindowsPath('c:/Downloads/final.txt')
>>> p = PureWindowsPath('c:/Downloads/pathlib.tar.gz')
>>> p.with_stem('lib')
PureWindowsPath('c:/Downloads/lib.gz')
>>> p = PureWindowsPath('c:/')
>>> p.with_stem('')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/antoine/cpython/default/Lib/pathlib.py", line 861, in with_stem
    return self.with_name(stem + self.suffix)
  File "/home/antoine/cpython/default/Lib/pathlib.py", line 851, in with_name
    raise ValueError("%r has an empty name" % (self,))
ValueError: PureWindowsPath('c:/') has an empty name

Added in version 3.9.

PurePath.with_suffix(suffix)

回傳一個修改 suffix 後的新路徑。如果原始路徑沒有後綴,新的 suffix 會附加在後面。如果 suffix 是一個空字串,原來的後綴會被移除:

>>> p = PureWindowsPath('c:/Downloads/pathlib.tar.gz')
>>> p.with_suffix('.bz2')
PureWindowsPath('c:/Downloads/pathlib.tar.bz2')
>>> p = PureWindowsPath('README')
>>> p.with_suffix('.txt')
PureWindowsPath('README.txt')
>>> p = PureWindowsPath('README.txt')
>>> p.with_suffix('')
PureWindowsPath('README')

在 3.14 版的變更: A single dot (".") is considered a valid suffix. In previous versions, ValueError is raised if a single dot is supplied.

PurePath.with_segments(*pathsegments)

透過結合給定的 pathsegments 建立一個相同類型的新路徑物件,當一個衍生路徑被建立的時候會呼叫這個方法,例如從 parentrelative_to() 建立衍生路徑。子類別可以覆寫此方法來傳遞資訊給衍生路徑,例如:

from pathlib import PurePosixPath

class MyPath(PurePosixPath):
    def __init__(self, *pathsegments, session_id):
        super().__init__(*pathsegments)
        self.session_id = session_id

    def with_segments(self, *pathsegments):
        return type(self)(*pathsegments, session_id=self.session_id)

etc = MyPath('/etc', session_id=42)
hosts = etc / 'hosts'
print(hosts.session_id)  # 42

Added in version 3.12.

實體路徑

實體路徑是純路徑類別的子類別。除了後者本來就有提供的操作,它們也提供方法可以對路徑物件做系統呼叫。有三種方式可以實例化實體路徑:

class pathlib.Path(*pathsegments)

PurePath 的子類別,此類別表示系統的路徑類型的實體路徑(實例化時會建立一個 PosixPathWindowsPath):

>>> Path('setup.py')
PosixPath('setup.py')

pathsegments 的指定方式與 PurePath 類似。

class pathlib.PosixPath(*pathsegments)

PathPurePosixPath 的子類別,此類別表示實體非 Windows 檔案系統路徑:

>>> PosixPath('/etc')
PosixPath('/etc')

pathsegments 的指定方式與 PurePath 類似。

在 3.13 版的變更: Raises UnsupportedOperation on Windows. In previous versions, NotImplementedError was raised instead.

class pathlib.WindowsPath(*pathsegments)

PathPureWindowsPath 的子類別,此類別表示實體 Windows 檔案系統路徑:

>>> WindowsPath('c:/Program Files/')
WindowsPath('c:/Program Files')

pathsegments 的指定方式與 PurePath 類似。

在 3.13 版的變更: Raises UnsupportedOperation on non-Windows platforms. In previous versions, NotImplementedError was raised instead.

你只能實例化對應你的系統的類別類型(允許在不相容的路徑類型上做系統呼叫可能在你的應用程式導致漏洞或故障):

>>> import os
>>> os.name
'posix'
>>> Path('setup.py')
PosixPath('setup.py')
>>> PosixPath('setup.py')
PosixPath('setup.py')
>>> WindowsPath('setup.py')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "pathlib.py", line 798, in __new__
    % (cls.__name__,))
UnsupportedOperation: cannot instantiate 'WindowsPath' on your system

有些實體路徑方法會在系統呼叫失敗(例如因為路徑不存在)時引發 OSError

Parsing and generating URIs

Concrete path objects can be created from, and represented as, 'file' URIs conforming to RFC 8089.

備註

File URIs are not portable across machines with different filesystem encodings.

classmethod Path.from_uri(uri)

Return a new path object from parsing a 'file' URI. For example:

>>> p = Path.from_uri('file:///etc/hosts')
PosixPath('/etc/hosts')

On Windows, DOS device and UNC paths may be parsed from URIs:

>>> p = Path.from_uri('file:///c:/windows')
WindowsPath('c:/windows')
>>> p = Path.from_uri('file://server/share')
WindowsPath('//server/share')

Several variant forms are supported:

>>> p = Path.from_uri('file:////server/share')
WindowsPath('//server/share')
>>> p = Path.from_uri('file://///server/share')
WindowsPath('//server/share')
>>> p = Path.from_uri('file:c:/windows')
WindowsPath('c:/windows')
>>> p = Path.from_uri('file:/c|/windows')
WindowsPath('c:/windows')

ValueError is raised if the URI does not start with file:, or the parsed path isn't absolute.

Added in version 3.13.

Path.as_uri()

Represent the path as a 'file' URI. ValueError is raised if the path isn't absolute.

>>> p = PosixPath('/etc/passwd')
>>> p.as_uri()
'file:///etc/passwd'
>>> p = WindowsPath('c:/Windows')
>>> p.as_uri()
'file:///c:/Windows'

For historical reasons, this method is also available from PurePath objects. However, its use of os.fsencode() makes it strictly impure.

Querying file type and status

在 3.8 版的變更: exists()is_dir()is_file()is_mount()is_symlink()is_block_device()is_char_device()is_fifo()is_socket() 遇到路徑包含 OS 層無法表示的字元時現在會回傳 False 而不是引發例外。

在 3.14 版的變更: The methods given above now return False instead of raising any OSError exception from the operating system. In previous versions, some kinds of OSError exception are raised, and others suppressed. The new behaviour is consistent with os.path.exists(), os.path.isdir(), etc. Use stat() to retrieve the file status without suppressing exceptions.

Path.stat(*, follow_symlinks=True)

回傳一個包含該路徑資訊的 os.stat_result 物件,像 os.stat() 一樣。每次呼叫此方法都會重新查詢結果。

此方法通常會跟隨 (follow) 符號連結;想要取得符號連結的資訊,可以加上引數 follow_symlinks=False 或使用 lstat()

>>> p = Path('setup.py')
>>> p.stat().st_size
956
>>> p.stat().st_mtime
1327883547.852554

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

Path.lstat()

類似 Path.stat(),但如果該路徑指向一個符號連結,則回傳符號連結的資訊而不是其指向的目標。

Path.exists(*, follow_symlinks=True)

Return True if the path points to an existing file or directory. False will be returned if the path is invalid, inaccessible or missing. Use Path.stat() to distinguish between these cases.

此方法通常會跟隨符號連結;如果想檢查符號連結是否存在,可以加上引數 follow_symlinks=False

>>> Path('.').exists()
True
>>> Path('setup.py').exists()
True
>>> Path('/etc').exists()
True
>>> Path('nonexistentfile').exists()
False

在 3.12 版的變更: 新增 follow_symlinks 參數。

Path.is_file(*, follow_symlinks=True)

Return True if the path points to a regular file. False will be returned if the path is invalid, inaccessible or missing, or if it points to something other than a regular file. Use Path.stat() to distinguish between these cases.

This method normally follows symlinks; to exclude symlinks, add the argument follow_symlinks=False.

在 3.13 版的變更: 新增 follow_symlinks 參數。

Path.is_dir(*, follow_symlinks=True)

Return True if the path points to a directory. False will be returned if the path is invalid, inaccessible or missing, or if it points to something other than a directory. Use Path.stat() to distinguish between these cases.

This method normally follows symlinks; to exclude symlinks to directories, add the argument follow_symlinks=False.

在 3.13 版的變更: 新增 follow_symlinks 參數。

Return True if the path points to a symbolic link, even if that symlink is broken. False will be returned if the path is invalid, inaccessible or missing, or if it points to something other than a symbolic link. Use Path.stat() to distinguish between these cases.

Path.is_junction()

如果該路徑指向一個連接點 (junction) 則回傳 True,對其他類型的檔案則回傳 False。目前只有 Windows 支援連接點。

Added in version 3.12.

Path.is_mount()

如果路徑是一個 mount point(一個檔案系統裡掛載不同檔案系統的存取點)則回傳 True。在 POSIX 上,此函式檢查 path 的父路徑 path/.. 是否和 path 在不同的裝置上,或者 path/..path 是否指向相同裝置的相同 i-node ── 這對於所有 Unix 和 POSIX 變體來說應該會偵測出掛載點。在 Windows 上,一個掛載點被視為一個根磁碟機字母(例如 c:\)、一個 UNC share(例如 \\server\share)或是掛載的檔案系統目錄。

Added in version 3.7.

在 3.12 版的變更: 加入對 Windows 的支援。

Path.is_socket()

Return True if the path points to a Unix socket. False will be returned if the path is invalid, inaccessible or missing, or if it points to something other than a Unix socket. Use Path.stat() to distinguish between these cases.

Path.is_fifo()

Return True if the path points to a FIFO. False will be returned if the path is invalid, inaccessible or missing, or if it points to something other than a FIFO. Use Path.stat() to distinguish between these cases.

Path.is_block_device()

Return True if the path points to a block device. False will be returned if the path is invalid, inaccessible or missing, or if it points to something other than a block device. Use Path.stat() to distinguish between these cases.

Path.is_char_device()

Return True if the path points to a character device. False will be returned if the path is invalid, inaccessible or missing, or if it points to something other than a character device. Use Path.stat() to distinguish between these cases.

Path.samefile(other_path)

回傳此路徑是否指向與 other_path 相同的檔案,other_path 可以是路徑 (Path) 物件或字串。其語義類似於 os.path.samefile()os.path.samestat()

若任何一個檔案因為某些原因無法存取,則引發 OSError

>>> p = Path('spam')
>>> q = Path('eggs')
>>> p.samefile(q)
False
>>> p.samefile('spam')
True

Added in version 3.5.

Reading and writing files

Path.open(mode='r', buffering=-1, encoding=None, errors=None, newline=None)

開啟該路徑指向的檔案,像內建的 open() 函式做的一樣:

>>> p = Path('setup.py')
>>> with p.open() as f:
...     f.readline()
...
'#!/usr/bin/env python3\n'
Path.read_text(encoding=None, errors=None, newline=None)

將路徑指向的檔案的解碼內容以字串形式回傳:

>>> p = Path('my_text_file')
>>> p.write_text('Text file contents')
18
>>> p.read_text()
'Text file contents'

該檔案被打開並且隨後關閉。可選參數的含義與 open() 中的相同。

Added in version 3.5.

在 3.13 版的變更: 新增 newline 參數。

Path.read_bytes()

將路徑指向的檔案的二進位內容以一個位元組物件回傳:

>>> p = Path('my_binary_file')
>>> p.write_bytes(b'Binary file contents')
20
>>> p.read_bytes()
b'Binary file contents'

Added in version 3.5.

Path.write_text(data, encoding=None, errors=None, newline=None)

以文字模式開啟指向的檔案,將 data 寫到檔案,並關閉檔案:: :

>>> p = Path('my_text_file')
>>> p.write_text('Text file contents')
18
>>> p.read_text()
'Text file contents'

一個名稱相同的已存在檔案會被覆寫。可選參數和 open() 的參數有相同意義。

Added in version 3.5.

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

Path.write_bytes(data)

以位元組模式開啟指向的檔案,將 data 寫到檔案,並關閉檔案:: :

>>> p = Path('my_binary_file')
>>> p.write_bytes(b'Binary file contents')
20
>>> p.read_bytes()
b'Binary file contents'

一個名稱相同的已存在檔案會被覆寫。

Added in version 3.5.

讀取目錄

Path.iterdir()

當該路徑指向一個目錄,會 yield 目錄裡面的路徑物件:

>>> p = Path('docs')
>>> for child in p.iterdir(): child
...
PosixPath('docs/conf.py')
PosixPath('docs/_templates')
PosixPath('docs/make.bat')
PosixPath('docs/index.rst')
PosixPath('docs/_build')
PosixPath('docs/_static')
PosixPath('docs/Makefile')

子路徑會以任意順序被 yield,且不會包含特殊項目 '.''..'。如果一個檔案在建立這個疊代器之後加到該目錄或從目錄刪除,這個檔案的路徑物件是否會被包含是沒有明定的。

If the path is not a directory or otherwise inaccessible, OSError is raised.

Path.glob(pattern, *, case_sensitive=None, recurse_symlinks=False)

在該路徑表示的目錄裡,以 glob 方式比對所給定的相對 pattern,並 yield 所有比對到的檔案(任意類型):

>>> sorted(Path('.').glob('*.py'))
[PosixPath('pathlib.py'), PosixPath('setup.py'), PosixPath('test_pathlib.py')]
>>> sorted(Path('.').glob('*/*.py'))
[PosixPath('docs/conf.py')]
>>> sorted(Path('.').glob('**/*.py'))
[PosixPath('build/lib/pathlib.py'),
 PosixPath('docs/conf.py'),
 PosixPath('pathlib.py'),
 PosixPath('setup.py'),
 PosixPath('test_pathlib.py')]

也參考

Pattern language documentation.

預設情況下,或者當 case_sensitive 僅限關鍵字引數被設定為 None 的時候,此方法會使用平台特定的大小寫規則來比對路徑;通常在 POSIX 上會區分大小寫,而在 Windows 上不區分大小寫。將 case_sensitive 設成 TrueFalse 會覆寫這個行為。

By default, or when the recurse_symlinks keyword-only argument is set to False, this method follows symlinks except when expanding "**" wildcards. Set recurse_symlinks to True to always follow symlinks.

引發一個附帶引數 selfpattern稽核事件 pathlib.Path.glob

在 3.12 版的變更: 新增 case_sensitive 參數。

在 3.13 版的變更: The recurse_symlinks parameter was added.

在 3.13 版的變更: The pattern parameter accepts a path-like object.

在 3.13 版的變更: Any OSError exceptions raised from scanning the filesystem are suppressed. In previous versions, such exceptions are suppressed in many cases, but not all.

Path.rglob(pattern, *, case_sensitive=None, recurse_symlinks=False)

Glob the given relative pattern recursively. This is like calling Path.glob() with "**/" added in front of the pattern.

也參考

Pattern language and Path.glob() documentation.

引發一個附帶引數 selfpattern稽核事件 pathlib.Path.rglob

在 3.12 版的變更: 新增 case_sensitive 參數。

在 3.13 版的變更: The recurse_symlinks parameter was added.

在 3.13 版的變更: The pattern parameter accepts a path-like object.

Path.walk(top_down=True, on_error=None, follow_symlinks=False)

透過由上而下或由下而上地走訪目錄樹產生目錄樹裡的檔案名稱。

對每個以 self 為根且在目錄樹裡的目錄(包含 self 但不包含 '.' 和 '..' ),此方法會 yield 一個 (dirpath, dirnames, filenames) 的三元素元組。

dirpath 是一個目前走訪到的目錄的 Pathdirnames 是一個 dirpath 裡的子目錄名稱的字串串列(不包含 '.''..' ),而 filenames 是一個 dirpath 裡非目錄檔案名稱的字串串列。要取得在 dirpath 裡檔案或目錄的完整路徑(以 self 開頭),可以使用 dirpath / name。會根據檔案系統來決定串列是否有排序。

如果可選引數 top_down 是 true(預設值),一個目錄的三元素元組會在其任何子目錄的三元素元組之前產生(目錄是由上而下走訪)。如果 top_down 是 false,一個目錄的三元素元組會在其所有子目錄的三元素元組之後產生(目錄是由下而上走訪)。不論 top_down 的值是什麼,子目錄的串列會在走訪該目錄及其子目錄的三元素元組之前取得。

top_down 是 true,呼叫者可以原地 (in-place) 修改 dirnames 串列(例如使用 del 或切片賦值 (slice assignment)),且 Path.walk() 只會遞迴進名稱依然留在 dirnames 裡的子目錄。這可以用來修剪搜尋,或者強加特定順序的訪問,或者甚至在繼續 Path.walk() 之前,用來告訴 Path.walk() 關於呼叫者建立或重新命名的目錄。當 top_down 是 false 的時候,修改 dirnamesPath.walk() 的行為沒有影響,因為 dirnames 裡的目錄已經在 dirnames yield 給呼叫者之前被產生。

預設來自 os.scandir() 的錯誤會被忽略。如果指定了可選引數 on_error(它應該要是一個可呼叫物件),它會被以一個 OSError 實例為引數來呼叫。這個可呼叫物件可以處理錯誤以繼續走訪,或者再次引發錯誤來停止走訪。注意,檔案名稱可以從例外物件的 filename 屬性來取得。

預設 Path.walk() 不會跟隨符號連結,而是會把它們加到 filenames 串列。將 follow_symlinks 設定為 true 會解析符號連結,並將它們根據其指向的目標放在適當的 dirnamesfilenames,而因此訪問到符號連結指向的目錄(在有支援符號連結的地方)。

備註

需要注意的是如果符號連結指向一個其本身的父目錄,則將 follow_symlinks 設定為 true 會導致無窮的遞迴。Path.walk() 不會紀錄其已經訪問過的目錄。

備註

Path.walk() 假設其走訪的目錄在執行過程中不會被修改。舉例來說,如果在 dirnames 裡的目錄已經被一個符號連結取代,且 follow_symlinks 是 false,Path.walk() 依然會試著往下進入它。為了防止這樣的行為,可以從 dirnames 適當地移除目錄。

備註

如果 follow_symlinks 是 false,和 os.walk() 行為不同的是 Path.walk() 會將指向目錄的符號連結放在 filenames 串列。

這個範例會顯示在每個目錄裡所有檔案使用的位元組數量,同時間忽略 __pycache__ 目錄:

from pathlib import Path
for root, dirs, files in Path("cpython/Lib/concurrent").walk(on_error=print):
  print(
      root,
      "consumes",
      sum((root / file).stat().st_size for file in files),
      "bytes in",
      len(files),
      "non-directory files"
  )
  if '__pycache__' in dirs:
        dirs.remove('__pycache__')

下一個範例是 shutil.rmtree() 的一個簡單的實作方式。由下而上走訪目錄樹是必要的,因為 rmdir() 不允許在目錄為空之前刪除它:

# Delete everything reachable from the directory "top".
# CAUTION:  This is dangerous! For example, if top == Path('/'),
# it could delete all of your files.
for root, dirs, files in top.walk(top_down=False):
    for name in files:
        (root / name).unlink()
    for name in dirs:
        (root / name).rmdir()

Added in version 3.12.

Creating files and directories

Path.touch(mode=0o666, exist_ok=True)

Create a file at this given path. If mode is given, it is combined with the process's umask value to determine the file mode and access flags. If the file already exists, the function succeeds when exist_ok is true (and its modification time is updated to the current time), otherwise FileExistsError is raised.

也參考

The open(), write_text() and write_bytes() methods are often used to create files.

Path.mkdir(mode=0o777, parents=False, exist_ok=False)

Create a new directory at this given path. If mode is given, it is combined with the process's umask value to determine the file mode and access flags. If the path already exists, FileExistsError is raised.

如果 parents 是 true,則任何缺少的父路徑都會依需要被建立;它們不考慮 mode 而會以預設的權限來建立(模仿 POSIX 的 mkdir -p 指令)。

如果 parents 是 false(預設值),缺少的父路徑會引發 FileNotFoundError

如果 exist_ok 是 false(預設值),則當目標目錄已經存在的話會引發 FileExistsError

如果 exist_ok 是 true,只有當最後的路徑組成不是一個已存在的非目錄檔案,FileExistsError 例外會被忽略(與 POSIX 的 mkdir -p 指令行為相同)。

在 3.5 版的變更: 新增 exist_ok 參數。

使這個路徑成為一個指向 target 的符號連結。

On Windows, a symlink represents either a file or a directory, and does not morph to the target dynamically. If the target is present, the type of the symlink will be created to match. Otherwise, the symlink will be created as a directory if target_is_directory is true or a file symlink (the default) otherwise. On non-Windows platforms, target_is_directory is ignored.

>>> p = Path('mylink')
>>> p.symlink_to('setup.py')
>>> p.resolve()
PosixPath('/home/antoine/pathlib/setup.py')
>>> p.stat().st_size
956
>>> p.lstat().st_size
8

備註

引數的順序 (link, target) 和 os.symlink() 相反。

在 3.13 版的變更: Raises UnsupportedOperation if os.symlink() is not available. In previous versions, NotImplementedError was raised.

使這個路徑成為與 target 相同檔案的一個硬連結 (hard link)。

備註

引數的順序 (link, target) 和 os.link() 相反。

Added in version 3.10.

在 3.13 版的變更: Raises UnsupportedOperation if os.link() is not available. In previous versions, NotImplementedError was raised.

Copying, renaming and deleting

Path.copy(target, *, follow_symlinks=True)

Copy the contents of this file to the target file. If target specifies a file that already exists, it will be replaced.

If follow_symlinks is false, and this file is a symbolic link, target will be created as a symbolic link. If follow_symlinks is true and this file is a symbolic link, target will be a copy of the symlink target.

備註

This method uses operating system functionality to copy file content efficiently. The OS might also copy some metadata, such as file permissions. After the copy is complete, users may wish to call Path.chmod() to set the permissions of the target file.

警告

On old builds of Windows (before Windows 10 build 19041), this method raises OSError when a symlink to a directory is encountered and follow_symlinks is false.

Added in version 3.14.

Path.copytree(target, *, follow_symlinks=True, dirs_exist_ok=False, ignore=None, on_error=None)

Recursively copy this directory tree to the given destination.

If a symlink is encountered in the source tree, and follow_symlinks is true (the default), the symlink's target is copied. Otherwise, the symlink is recreated in the destination tree.

If the destination is an existing directory and dirs_exist_ok is false (the default), a FileExistsError is raised. Otherwise, the copying operation will continue if it encounters existing directories, and files within the destination tree will be overwritten by corresponding files from the source tree.

If ignore is given, it should be a callable accepting one argument: a file or directory path within the source tree. The callable may return true to suppress copying of the path.

If on_error is given, it should be a callable accepting one argument: an instance of OSError. The callable may re-raise the exception or do nothing, in which case the copying operation continues. If on_error isn't given, exceptions are propagated to the caller.

Added in version 3.14.

Path.rename(target)

Rename this file or directory to the given target, and return a new Path instance pointing to target. On Unix, if target exists and is a file, it will be replaced silently if the user has permission. On Windows, if target exists, FileExistsError will be raised. target can be either a string or another path object:

>>> p = Path('foo')
>>> p.open('w').write('some text')
9
>>> target = Path('bar')
>>> p.rename(target)
PosixPath('bar')
>>> target.open().read()
'some text'

The target path may be absolute or relative. Relative paths are interpreted relative to the current working directory, not the directory of the Path object.

此功能是使用 os.rename() 實現的,並提供相同的保證。

在 3.8 版的變更: Added return value, return the new Path instance.

Path.replace(target)

Rename this file or directory to the given target, and return a new Path instance pointing to target. If target points to an existing file or empty directory, it will be unconditionally replaced.

The target path may be absolute or relative. Relative paths are interpreted relative to the current working directory, not the directory of the Path object.

在 3.8 版的變更: Added return value, return the new Path instance.

移除這個檔案或符號連結。如果路徑指向目錄,請改用 Path.rmdir()

如果 missing_ok 是 false(預設值),FileNotFoundError 會在路徑不存在時被引發。

如果 missing_ok 是 true,FileNotFoundError 例外會被忽略(行為與 POSIX rm -f 指令相同)。

在 3.8 版的變更: 新增 missing_ok 參數。

Path.rmdir()

移除此目錄。該目錄必須為空。

Permissions and ownership

Path.owner(*, follow_symlinks=True)

Return the name of the user owning the file. KeyError is raised if the file's user identifier (UID) isn't found in the system database.

This method normally follows symlinks; to get the owner of the symlink, add the argument follow_symlinks=False.

在 3.13 版的變更: Raises UnsupportedOperation if the pwd module is not available. In earlier versions, NotImplementedError was raised.

在 3.13 版的變更: 新增 follow_symlinks 參數。

Path.group(*, follow_symlinks=True)

Return the name of the group owning the file. KeyError is raised if the file's group identifier (GID) isn't found in the system database.

This method normally follows symlinks; to get the group of the symlink, add the argument follow_symlinks=False.

在 3.13 版的變更: Raises UnsupportedOperation if the grp module is not available. In earlier versions, NotImplementedError was raised.

在 3.13 版的變更: 新增 follow_symlinks 參數。

Path.chmod(mode, *, follow_symlinks=True)

修改檔案模式 (file mode) 與權限,像 os.chmod() 一樣。

此方法通常會跟隨符號連結。一些 Unix 類型支援修改符號連結本身的權限;在這些平台上你可以加上引數 follow_symlinks=False 或使用 lchmod()

>>> p = Path('setup.py')
>>> p.stat().st_mode
33277
>>> p.chmod(0o444)
>>> p.stat().st_mode
33060

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

Path.lchmod(mode)

類似 Path.chmod(),但如果該路徑指向一個符號連結,則符號連結的模式 (mode) 會被改變而不是其指向的目標。

其他方法

classmethod Path.cwd()

回傳一個代表目前目錄的新的路徑物件(像 os.getcwd() 回傳的一樣):

>>> Path.cwd()
PosixPath('/home/antoine/pathlib')
classmethod Path.home()

回傳一個代表使用者家目錄的新的路徑物件(像以 ~ 構成的 os.path.expanduser() 的回傳一樣)。如果無法解析家目錄,會引發 RuntimeError

>>> Path.home()
PosixPath('/home/antoine')

Added in version 3.5.

Path.expanduser()

回傳一個展開 ~~user 構成的新路徑,像 os.path.expanduser() 回傳的一樣。如果無法解析家目錄,會引發 RuntimeError

>>> p = PosixPath('~/films/Monty Python')
>>> p.expanduser()
PosixPath('/home/eric/films/Monty Python')

Added in version 3.5.

回傳符號連結指向的路徑(如 os.readlink() 的回傳值):

>>> p = Path('mylink')
>>> p.symlink_to('setup.py')
>>> p.readlink()
PosixPath('setup.py')

Added in version 3.9.

在 3.13 版的變更: Raises UnsupportedOperation if os.readlink() is not available. In previous versions, NotImplementedError was raised.

Path.absolute()

將路徑轉換為絕對路徑,不進行標準化或解析符號連結。回傳一個新的路徑物件:

>>> p = Path('tests')
>>> p
PosixPath('tests')
>>> p.absolute()
PosixPath('/home/antoine/pathlib/tests')
Path.resolve(strict=False)

將路徑轉換為絕對路徑,解析所有符號連結。回傳一個新的路徑物件:

>>> p = Path()
>>> p
PosixPath('.')
>>> p.resolve()
PosixPath('/home/antoine/pathlib')

同時也會消除 ".." 的路徑組成(只有此方法這樣做):

>>> p = Path('docs/../setup.py')
>>> p.resolve()
PosixPath('/home/antoine/pathlib/setup.py')

If a path doesn't exist or a symlink loop is encountered, and strict is True, OSError is raised. If strict is False, the path is resolved as far as possible and any remainder is appended without checking whether it exists.

在 3.6 版的變更: 新增 strict 參數(在 3.6 版本之前的行為是嚴格的)。

在 3.13 版的變更: Symlink loops are treated like other errors: OSError is raised in strict mode, and no exception is raised in non-strict mode. In previous versions, RuntimeError is raised no matter the value of strict.

Pattern language

The following wildcards are supported in patterns for full_match(), glob() and rglob():

** (entire segment)

Matches any number of file or directory segments, including zero.

* (entire segment)

Matches one file or directory segment.

* (part of a segment)

Matches any number of non-separator characters, including zero.

?

Matches one non-separator character.

[seq]

Matches one character in seq.

[!seq]

Matches one character not in seq.

For a literal match, wrap the meta-characters in brackets. For example, "[?]" matches the character "?".

The "**" wildcard enables recursive globbing. A few examples:

模式

含意

"**/*"

Any path with at least one segment.

"**/*.py"

Any path with a final segment ending ".py".

"assets/**"

Any path starting with "assets/".

"assets/**/*"

Any path starting with "assets/", excluding "assets/" itself.

備註

Globbing with the "**" wildcard visits every directory in the tree. Large directory trees may take a long time to search.

在 3.13 版的變更: Globbing with a pattern that ends with "**" returns both files and directories. In previous versions, only directories were returned.

In Path.glob() and rglob(), a trailing slash may be added to the pattern to match only directories.

在 3.11 版的變更: Globbing with a pattern that ends with a pathname components separator (sep or altsep) returns only directories.

Comparison to the glob module

The patterns accepted and results generated by Path.glob() and Path.rglob() differ slightly from those by the glob module:

  1. Files beginning with a dot are not special in pathlib. This is like passing include_hidden=True to glob.glob().

  2. "**" pattern components are always recursive in pathlib. This is like passing recursive=True to glob.glob().

  3. "**" pattern components do not follow symlinks by default in pathlib. This behaviour has no equivalent in glob.glob(), but you can pass recurse_symlinks=True to Path.glob() for compatible behaviour.

  4. Like all PurePath and Path objects, the values returned from Path.glob() and Path.rglob() don't include trailing slashes.

  5. The values returned from pathlib's path.glob() and path.rglob() include the path as a prefix, unlike the results of glob.glob(root_dir=path).

  6. The values returned from pathlib's path.glob() and path.rglob() may include path itself, for example when globbing "**", whereas the results of glob.glob(root_dir=path) never include an empty string that would correspond to path.

Comparison to the os and os.path modules

pathlib implements path operations using PurePath and Path objects, and so it's said to be object-oriented. On the other hand, the os and os.path modules supply functions that work with low-level str and bytes objects, which is a more procedural approach. Some users consider the object-oriented style to be more readable.

Many functions in os and os.path support bytes paths and paths relative to directory descriptors. These features aren't available in pathlib.

Python's str and bytes types, and portions of the os and os.path modules, are written in C and are very speedy. pathlib is written in pure Python and is often slower, but rarely slow enough to matter.

pathlib's path normalization is slightly more opinionated and consistent than os.path. For example, whereas os.path.abspath() eliminates ".." segments from a path, which may change its meaning if symlinks are involved, Path.absolute() preserves these segments for greater safety.

pathlib's path normalization may render it unsuitable for some applications:

  1. pathlib normalizes Path("my_folder/") to Path("my_folder"), which changes a path's meaning when supplied to various operating system APIs and command-line utilities. Specifically, the absence of a trailing separator may allow the path to be resolved as either a file or directory, rather than a directory only.

  2. pathlib normalizes Path("./my_program") to Path("my_program"), which changes a path's meaning when used as an executable search path, such as in a shell or when spawning a child process. Specifically, the absence of a separator in the path may force it to be looked up in PATH rather than the current directory.

As a consequence of these differences, pathlib is not a drop-in replacement for os.path.

Corresponding tools

以下是一張表格,對應許多 os 函式及其相符於 PurePath/Path 的項目。

osos.path

pathlib

os.path.abspath()

Path.absolute()

os.path.realpath()

Path.resolve()

os.chmod()

Path.chmod()

os.mkdir()

Path.mkdir()

os.makedirs()

Path.mkdir()

os.rename()

Path.rename()

os.replace()

Path.replace()

os.rmdir()

Path.rmdir()

os.remove()os.unlink()

Path.unlink()

os.getcwd()

Path.cwd()

os.path.exists()

Path.exists()

os.path.expanduser()

Path.expanduser()Path.home()

os.listdir()

Path.iterdir()

os.walk()

Path.walk()

os.path.isdir()

Path.is_dir()

os.path.isfile()

Path.is_file()

os.path.islink()

Path.is_symlink()

os.link()

Path.hardlink_to()

os.symlink()

Path.symlink_to()

os.readlink()

Path.readlink()

os.path.relpath()

PurePath.relative_to()

os.stat()

Path.stat()Path.owner()Path.group()

os.path.isabs()

PurePath.is_absolute()

os.path.join()

PurePath.joinpath()

os.path.basename()

PurePath.name

os.path.dirname()

PurePath.parent

os.path.samefile()

Path.samefile()

os.path.splitext()

PurePath.stemPurePath.suffix