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

在 3.4 版被加入.

**Source code:** Lib/pathlib/

======================================================================

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

[圖片：Inheritance diagram showing the classes available in pathlib.
The most basic class is PurePath, which has three direct subclasses:
PurePosixPath, PureWindowsPath, and Path. Further to these four
classes, there are two classes that use multiple inheritance:
PosixPath subclasses PurePosixPath and Path, and WindowsPath
subclasses PureWindowsPath and Path.][圖片]

如果你之前從未使用過此模組或不確定哪個類別適合你的任務，那你需要的最有
可能是 "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'


Exceptions
==========

exception pathlib.UnsupportedOperation

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

   在 3.13 版被加入.


純路徑
======

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

class pathlib.PurePath(*pathsegments)

   一個通用的類別，表示系統的路徑類型（實例化時會建立一個
   "PurePosixPath" 或 "PureWindowsPath")：

      >>> 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/hosts')
      PurePosixPath('/etc/hosts')

   *pathsegments* 的指定方式與 "PurePath" 類似。

class pathlib.PureWindowsPath(*pathsegments)

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

      >>> PureWindowsPath('c:/', 'Users', 'Ximénez')
      PureWindowsPath('c:/Users/Ximénez')
      >>> 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".

   在 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.

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
      []

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

   在 3.9 版被加入.

   Deprecated since version 3.12, will be removed in version 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.

   Deprecated since version 3.13, will be removed in version 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* 設定成 "True" 或 "False" 會覆蓋這個行為。

   在 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"
   相同）。

   Deprecated since version 3.12, will be removed in version 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

   在 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')

PurePath.with_segments(*pathsegments)

   透過結合給定的 *pathsegments* 建立一個相同類型的新路徑物件，當一個
   衍生路徑被建立的時候會呼叫這個方法，例如從 "parent" 和
   "relative_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

   在 3.12 版被加入.


實體路徑
========

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

class pathlib.Path(*pathsegments)

   "PurePath" 的子類別，此類別表示系統的路徑類型的實體路徑（實例化時會
   建立一個 "PosixPath" 或 "WindowsPath"）：

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

   *pathsegments* 的指定方式與 "PurePath" 類似。

class pathlib.PosixPath(*pathsegments)

   "Path" 和 "PurePosixPath" 的子類別，此類別表示實體非 Windows 檔案系
   統路徑：

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

   *pathsegments* 的指定方式與 "PurePath" 類似。

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

class pathlib.WindowsPath(*pathsegments)

   "Path" 和 "PureWindowsPath" 的子類別，此類別表示實體 Windows 檔案系
   統路徑：

      >>> WindowsPath('c:/', 'Users', 'Ximénez')
      WindowsPath('c:/Users/Ximénez')

   *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.

   在 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.


Expanding and resolving paths
-----------------------------

classmethod Path.home()

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

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

   在 3.5 版被加入.

Path.expanduser()

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

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

   在 3.5 版被加入.

classmethod Path.cwd()

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

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

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*.

Path.readlink()

   回傳符號連結指向的路徑（如 "os.readlink()" 的回傳值）：

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

   在 3.9 版被加入.

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


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" 而
不是引發例外。

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)

   如果路徑指向存在的檔案或目錄則回傳 "True"。

   此方法通常會跟隨符號連結；如果想檢查符號連結是否存在，可以加上引數
   "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" if it
   points to another kind of file.

   如果路徑不存在或者是一個斷掉的符號連結則也會回傳 "False"；其他錯誤
   （例如權限錯誤）則會傳遞出來。

   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" if it
   points to another kind of file.

   如果路徑不存在或者是一個斷掉的符號連結則也會回傳 "False"；其他錯誤
   （例如權限錯誤）則會傳遞出來。

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

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

Path.is_symlink()

   如果該路徑指向一個符號連結則回傳 "True"，否則回傳 "False"。

   如果該路徑不存在也會回傳 "False"；其他錯誤（例如權限錯誤）則會傳遞
   出來。

Path.is_junction()

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

   在 3.12 版被加入.

Path.is_mount()

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

   在 3.7 版被加入.

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

Path.is_socket()

   如果該路徑指向一個 Unix socket（或者是一個指向 Unix socket 的符號連
   結）則會回傳 "True"，如果指向其他類型的檔案則回傳 "False"。

   如果路徑不存在或者是一個斷掉的符號連結則也會回傳 "False"；其他錯誤
   （例如權限錯誤）則會傳遞出來。

Path.is_fifo()

   如果該路徑指向一個 FIFO（或者是一個指向 FIFO 的符號連結）則會回傳
   "True"，如果指向其他類型的檔案則回傳 "False"。

   如果路徑不存在或者是一個斷掉的符號連結則也會回傳 "False"；其他錯誤
   （例如權限錯誤）則會傳遞出來。

Path.is_block_device()

   如果該路徑指向一個區塊裝置 (block device)（或者是一個指向區塊裝置的
   符號連結）則會回傳 "True"，如果指向其他類型的檔案則回傳 "False"。

   如果路徑不存在或者是一個斷掉的符號連結則也會回傳 "False"；其他錯誤
   （例如權限錯誤）則會傳遞出來。

Path.is_char_device()

   如果該路徑指向一個字元裝置 (character device)（或者是一個指向字元裝
   置的符號連結）則會回傳 "True"，如果指向其他類型的檔案則回傳 "False"
   。

   如果路徑不存在或者是一個斷掉的符號連結則也會回傳 "False"；其他錯誤
   （例如權限錯誤）則會傳遞出來。

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

   在 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()" 中的相同。

   在 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'

   在 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()" 的參數有相同
   意義。

   在 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'

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

   在 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* 設成
   "True" 或 "False" 會覆寫這個行為。

   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.

   引發一個附帶引數 "self"、"pattern" 的稽核事件 "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.

   引發一個附帶引數 "self"、"pattern" 的稽核事件 "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* 是一個目前走訪到的目錄的 "Path"，*dirnames* 是一個
   *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 的時候，修改 *dirnames* 對 "Path.walk()" 的行為
   沒有影響，因為 *dirnames* 裡的目錄已經在 *dirnames* yield 給呼叫者
   之前被產生。

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

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

   備註:

     需要注意的是如果符號連結指向一個其本身的父目錄，則將
     *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()

   在 3.12 版被加入.


建立檔案與目錄
--------------

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

   根據給定路徑來建立一個檔案。如果 *mode* 有給定，它會與行程的
   "umask" 值結合，以確定檔案模式和存取旗標。當檔案已經存在時，若
   *exist_ok* 為 true 則函式不會失敗（其變更時間會被更新為當下時間），
   否則會引發 "FileExistsError"。

   也參考:

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

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

   在給定路徑下建立一個新的目錄。如果有給 *mode* 則會結合行程
   (process) 的 "umask" 值來決定檔案模式與存取旗標 (access flag)。如果
   路徑已經存在，會引發 "FileExistsError"。

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

   如果 *parents* 是 false（預設值），缺少的父路徑會引發
   "FileNotFoundError"。

   如果 *exist_ok* 是 false（預設值），則當目標目錄已經存在的話會引發
   "FileExistsError"。

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

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

Path.symlink_to(target, target_is_directory=False)

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

   在 Windows 上，符號連結代表一個檔案或目錄，且不會隨著目標 (target)
   動態改變。如果目標存在，則符號連結的類型會被建立來符合其目標。否則
   如果 *target_is_directory* 是 true，該符號連結會被建立成目錄，如果
   不是則建立成檔案（預設值）。在非 Windows 平台上，
   *target_is_directory* 會被忽略。

      >>> 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.

Path.hardlink_to(target)

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

   備註:

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

   在 3.10 版被加入.

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


Renaming and deleting
---------------------

Path.rename(target)

   將此檔案或目錄重新命名為給定的 *target* ，並回傳一個新的 "Path" 實
   例指向該 *target*。在 Unix 系統上，若 *target* 存在且為一個檔案，若
   使用者有權限，則會在不顯示訊息的情況下進行取代。在 Windows 系統上，
   若 *target* 存在，則會引發 "FileExistsError" 錯誤。*target* 可以是
   字串或另一個路徑物件：

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

   目標路徑可以是絕對路徑或相對路徑。相對路徑會相對於當前的工作目錄進
   行解釋，*而不是*相對於 "Path" 物件所在的目錄。

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

   在 3.8 版的變更: 新增了回傳值，回傳新的 "Path" 實例。

Path.replace(target)

   將此檔案或目錄重新命名為給定的 *target*，並回傳一個指向 *target* 的
   新 "Path" 實例。如果 *target* 指向一個現有的檔案或空目錄，它將被無
   條件地取代。

   目標路徑可以是絕對路徑或相對路徑。相對路徑會相對於當前的工作目錄進
   行解釋，*而不是*相對於 "Path" 物件所在的目錄。

   在 3.8 版的變更: 新增了回傳值，回傳新的 "Path" 實例。

Path.unlink(missing_ok=False)

   移除這個檔案或符號連結。如果路徑指向目錄，請改用 "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) 會被改變而不是其指向的目標。


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:

+---------------------------+-----------------------------------------------------------------------+
| Pattern                   | Meaning                                                               |
|===========================|=======================================================================|
| ""**/*""                  | 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" 的項目
。

+---------------------------------------+------------------------------------------------+
| "os" 和 "os.path"                     | "pathlib"                                      |
|=======================================|================================================|
| "os.path.dirname()"                   | "PurePath.parent"                              |
+---------------------------------------+------------------------------------------------+
| "os.path.basename()"                  | "PurePath.name"                                |
+---------------------------------------+------------------------------------------------+
| "os.path.splitext()"                  | "PurePath.stem" 和 "PurePath.suffix"           |
+---------------------------------------+------------------------------------------------+
| "os.path.join()"                      | "PurePath.joinpath()"                          |
+---------------------------------------+------------------------------------------------+
| "os.path.isabs()"                     | "PurePath.is_absolute()"                       |
+---------------------------------------+------------------------------------------------+
| "os.path.relpath()"                   | "PurePath.relative_to()" [1]                   |
+---------------------------------------+------------------------------------------------+
| "os.path.expanduser()"                | "Path.expanduser()" [2]                        |
+---------------------------------------+------------------------------------------------+
| "os.path.realpath()"                  | "Path.resolve()"                               |
+---------------------------------------+------------------------------------------------+
| "os.path.abspath()"                   | "Path.absolute()" [3]                          |
+---------------------------------------+------------------------------------------------+
| "os.path.exists()"                    | "Path.exists()"                                |
+---------------------------------------+------------------------------------------------+
| "os.path.isfile()"                    | "Path.is_file()"                               |
+---------------------------------------+------------------------------------------------+
| "os.path.isdir()"                     | "Path.is_dir()"                                |
+---------------------------------------+------------------------------------------------+
| "os.path.islink()"                    | "Path.is_symlink()"                            |
+---------------------------------------+------------------------------------------------+
| "os.path.isjunction()"                | "Path.is_junction()"                           |
+---------------------------------------+------------------------------------------------+
| "os.path.ismount()"                   | "Path.is_mount()"                              |
+---------------------------------------+------------------------------------------------+
| "os.path.samefile()"                  | "Path.samefile()"                              |
+---------------------------------------+------------------------------------------------+
| "os.getcwd()"                         | "Path.cwd()"                                   |
+---------------------------------------+------------------------------------------------+
| "os.stat()"                           | "Path.stat()"                                  |
+---------------------------------------+------------------------------------------------+
| "os.lstat()"                          | "Path.lstat()"                                 |
+---------------------------------------+------------------------------------------------+
| "os.listdir()"                        | "Path.iterdir()"                               |
+---------------------------------------+------------------------------------------------+
| "os.walk()"                           | "Path.walk()" [4]                              |
+---------------------------------------+------------------------------------------------+
| "os.mkdir()"、"os.makedirs()"         | "Path.mkdir()"                                 |
+---------------------------------------+------------------------------------------------+
| "os.link()"                           | "Path.hardlink_to()"                           |
+---------------------------------------+------------------------------------------------+
| "os.symlink()"                        | "Path.symlink_to()"                            |
+---------------------------------------+------------------------------------------------+
| "os.readlink()"                       | "Path.readlink()"                              |
+---------------------------------------+------------------------------------------------+
| "os.rename()"                         | "Path.rename()"                                |
+---------------------------------------+------------------------------------------------+
| "os.replace()"                        | "Path.replace()"                               |
+---------------------------------------+------------------------------------------------+
| "os.remove()"、"os.unlink()"          | "Path.unlink()"                                |
+---------------------------------------+------------------------------------------------+
| "os.rmdir()"                          | "Path.rmdir()"                                 |
+---------------------------------------+------------------------------------------------+
| "os.chmod()"                          | "Path.chmod()"                                 |
+---------------------------------------+------------------------------------------------+
| "os.lchmod()"                         | "Path.lchmod()"                                |
+---------------------------------------+------------------------------------------------+

-[ 註解 ]-

[1] "os.path.relpath()" calls "abspath()" to make paths absolute and
    remove "".."" parts, whereas "PurePath.relative_to()" is a lexical
    operation that raises "ValueError" when its inputs' anchors differ
    (e.g. if one path is absolute and the other relative.)

[2] "os.path.expanduser()" returns the path unchanged if the home
    directory can't be resolved, whereas "Path.expanduser()" raises
    "RuntimeError".

[3] "os.path.abspath()" removes "".."" components without resolving
    symlinks, which may change the meaning of the path, whereas
    "Path.absolute()" leaves any "".."" components in the path.

[4] "os.walk()" always follows symlinks when categorizing paths into
    *dirnames* and *filenames*, whereas "Path.walk()" categorizes all
    symlinks into *filenames* when *follow_symlinks* is false (the
    default.)
