pathlib --- 面向对象的文件系统路径

Added in version 3.4.

源代码:Lib/pathlib.py


该模块提供表示文件系统路径的类,其语义适用于不同的操作系统。路径类被分为提供纯计算操作而没有 I/O 的 纯路径,以及从纯路径继承而来但提供 I/O 操作的 具体路径。

继承关系图显示了 pathlib 中所有可用的类。 最基础的类是 PurePath,它有三个直接子类: PurePosixPath, PureWindowsPath 和 Path。 在这四个类之外,还有两个使用多重继承的类: PosixPath 子类 PurePosixPath 和 Path,以及 WindowsPath 子类 PureWindowsPath 和 Path。

如果以前从未用过此模块,或不确定哪个类适合完成任务,那要用的可能就是 Path。它在运行代码的平台上实例化为 具体路径。

在一些用例中纯路径很有用,例如:

  1. 如果你想要在 Unix 设备上操作 Windows 路径(或者相反)。你不应在 Unix 上实例化一个 WindowsPath,但是你可以实例化 PureWindowsPath。

  2. 你只想操作路径但不想实际访问操作系统。在这种情况下,实例化一个纯路径是有用的,因为它们没有任何访问操作系统的操作。

参见

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'

纯路径

纯路径对象提供了不实际访问文件系统的路径处理操作。有三种方式来访问这些类,也是不同的风格:

class pathlib.PurePath(*pathsegments)

一个通用的类,代表当前系统的路径风格(实例化为 PurePosixPath 或者 PureWindowsPath):

>>> PurePath('setup.py')      # 在 Unix 机器上运行
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') 时驱动器将不会被重置:

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

假斜杠和单个点号会被消除,但双点号 ('..') 和打头的双斜杠 ('//') 不会,因为这会出于各种原因改变路径的实际含义 (例如符号链接、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')

(一个很 naïve 的做法是让 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 相同。

无论你正运行什么系统,你都可以实例化这些类,因为它们提供的操作不做任何系统调用。

通用性质

路径是不可变并且 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'

运算符

斜杠操作符可以帮助创建子路径,如 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 将原始文件系统路径作为字节对象给出,就像被 os.fsencode() 编码一样:

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

备注

只推荐在 Unix 下调用 bytes。在 Windows, unicode 形式是文件系统路径的规范表示法。

访问个别部分

为了访问路径独立的部分 (组件),使用以下特征属性:

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

一个表示驱动器盘符或命名的字符串,如果存在:

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

UNC 分享也被认作驱动器:

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

一个表示(本地或全局)根的字符串,如果存在:

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

UNC 分享一样拥有根:

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

如果路径以超过两个连续斜框打头,PurePosixPath 会合并它们:

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

备注

此行为符合 The Open Group Base Specifications Issue 6, paragraph 4.11 Pathname Resolution:

"以连续两个斜杠打头的路径名可能会以具体实现所定义的方式被解读,但是两个以上的前缀斜杠则应当被当作一个斜杠来处理。"

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

提供访问此路径的逻辑祖先的不可变序列:

>>> 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 版本发生变更: parents 序列现在支持 切片 和负的索引值。

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('.')

备注

这是一个单纯的词法操作,因此有以下行为:

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

如果你想要向上遍历任意文件系统路径,建议首先调用 Path.resolve() 以便解析符号链接并消除 ".." 部分。

PurePath.name

一个表示最后路径组件的字符串,排除了驱动器与根目录,如果存在的话:

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

UNC 驱动器名不被考虑:

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

最终组件的文件扩展名(如果有):

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

一个路径文件扩展名的列表:

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

最后一个路径组件,除去后缀:

>>> 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.as_uri()

将路径表示为 file URI。 如果路径不是绝对路径,将引发 ValueError。

>>> p = PurePosixPath('/etc/passwd')
>>> p.as_uri()
'file:///etc/passwd'
>>> p = PureWindowsPath('c:/Windows')
>>> p.as_uri()
'file:///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.

Deprecated since version 3.12, will be removed in version 3.14: 传入附加参数的做法已被弃用;如果提供了附加参数,它们将与 other 合并。

PurePath.is_reserved()

在 PureWindowsPath,如果路径是被 Windows 保留的则返回 True,否则 False。在 PurePosixPath,总是返回 False。

>>> PureWindowsPath('nul').is_reserved()
True
>>> PurePosixPath('nul').is_reserved()
False

对保留路径的文件系统调用可能会莫名其妙地失败或产生意想不到的效果。

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.match(pattern, *, case_sensitive=None)

将此路径与所提供的 glob 样式匹配。如果匹配成功,则返回 True,否则返回 False。

如果 pattern 是相对路径,则路径既可以是相对路径,也可以是绝对路径,匹配从右边的开始:

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

如果 pattern 是绝对的,则路径必须是绝对的,并且路径必须完全匹配:

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

pattern 可以是另一个路径对象;这可以加快将同一模式与多个文件进行匹配的速度:

>>> pattern = PurePath('*.py')
>>> PurePath('a/b.py').match(pattern)
True

备注

此方法不支持递归通配符 "**"(它的作用类似于非递归的 "*")。

在 3.12 版本发生变更: 接受实现了 os.PathLike 接口的对象。

与其他方法一样,是否大小写敏感遵循平台的默认规则:

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

将 case_sensitive 设为 True 或 False 来覆盖此行为。

在 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 为(默认的)假值时,路径必须以 other 开始。 当参数为真值时,可能会添加 .. 条目以形成相对路径。 在所有其他情况下,例如路径引用了不同的驱动器,则会引发 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。如果原本路径没有 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')
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

Added in version 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 相同。

class pathlib.WindowsPath(*pathsegments)

Path 和 PureWindowsPath 的子类,从类表示一个 Windows 文件系统的具体路径:

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

pathsegments 参数的指定和 PurePath 相同。

你只能实例化与当前系统风格相同的类(允许系统调用作用于不兼容的路径风格可能在应用程序中导致缺陷或失败):

>>> 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__,))
NotImplementedError: cannot instantiate 'WindowsPath' on your system

某些具体路径方法在一个系统调用失败时(例如由于路径不存在)可能引发 OSError。

扩展和计算路径

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.

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

如果路径不存在并且 strict 设为 True,则抛出 FileNotFoundError。如果 strict 为 False,则路径将被尽可能地解析并且任何剩余部分都会被不检查是否存在地追加。如果在解析路径上发生无限循环,则抛出 RuntimeError。

在 3.6 版本发生变更: 增加了 strict 参数(3.6 之前的行为是默认采用 strict 模式)。

返回符号链接所指向的路径(即 os.readlink() 的返回值):

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

Added in version 3.9.

查询文件类型和状态

在 3.8 版本发生变更: 现在对于包含在 OS 层级上无法表示的字符的路径 exists(), is_dir(), is_file(), is_mount(), is_symlink(), is_block_device(), is_char_device(), is_fifo(), is_socket() 将返回 False 而不是引发异常。

Path.stat(*, follow_symlinks=True)

返回一个 os.stat_result 对象,其中包含有关此路径的信息,就像 os.stat()。 结果会在每次调用此方法时被查找。

此方法通常会跟随符号链接;要对 symlink 使用 stat 请添加参数 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()

如果文件指向一个常规文件(或指向常规文件的符号链接)则返回 True,指向其他类型的文件则返回 False。

当路径不存在或者是一个破损的符号链接时也会返回 False;其他错误(例如权限错误)被传播。

Path.is_dir()

如果文件指向一个目录(或指向目录的符号链接)则返回 True,指向其他类型的文件则返回 False。

当路径不存在或者是一个破损的符号链接时也会返回 False;其他错误(例如权限错误)被传播。

如果路径指向符号链接则返回 True, 否则 False。

如果路径不存在也返回 False;其他错误(例如权限错误)被传播。

Path.is_junction()

如果路径是指向一个接合点则返回 True,如果是其他文件类型则返回 False。 目前只有 Windows 支持接合点。

Added in version 3.12.

Path.is_mount()

如果路径是一个 挂载点: 在文件系统中被其他不同文件系统挂载的位置则返回 True。 在 POSIX 上,此函数将检查 path 的上一级 path/.. 是否位于和 path 不同的设备中,或者 path/.. 和 path 是否指向位于相同设置的相同 i-node --- 这应当能检测所有 Unix 和 POSIX 变种上的挂载点。 在 Windows 上,挂载点是被视为驱动器盘符的根目录 (例如 c:\)、UNC 共享目录 (例如 \\server\share) 或已挂载的文件系统目录。

Added in version 3.7.

在 3.12 版本发生变更: 添加了 Windows 支持。

Path.is_socket()

如果路径指向一个 Unix socket 文件(或者指向 Unix socket 文件的符号链接)则返回 True,如果指向其他类型的文件则返回 False。

当路径不存在或者是一个破损的符号链接时也会返回 False;其他错误(例如权限错误)被传播。

Path.is_fifo()

如果路径指向一个先进先出存储(或者指向先进先出存储的符号链接)则返回 True ,指向其他类型的文件则返回 False。

当路径不存在或者是一个破损的符号链接时也会返回 False;其他错误(例如权限错误)被传播。

Path.is_block_device()

如果文件指向一个块设备(或者指向块设备的符号链接)则返回 True,指向其他类型的文件则返回 False。

当路径不存在或者是一个破损的符号链接时也会返回 False;其他错误(例如权限错误)被传播。

Path.is_char_device()

如果路径指向一个字符设备(或指向字符设备的符号链接)则返回 True,指向其他类型的文件则返回 False。

当路径不存在或者是一个破损的符号链接时也会返回 False;其他错误(例如权限错误)被传播。

Path.samefile(other_path)

返回此目录是否指向与可能是字符串或者另一个路径对象的 other_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.

读写文件

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)

以字符串形式返回路径指向的文件的解码后文本内容。

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

文件先被打开然后关闭。有和 open() 一样的可选形参。

Added in version 3.5.

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()

当路径指向一个目录时,产生该路径下的对象的路径:

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

子条目会以任意顺序产生,并且不包括特殊条目 '.' 和 '..'。 如果迭代器创建之后有文件在目录中被移除或添加,是否要包括该文件所对应的路径对象并没有明确规定。

如果该路径不是一个目录或是无法访问,则会引发 OSError。

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

解析相对于此路径的通配符 pattern,产生所有匹配的文件:

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

pattern 的形式与 fnmatch 的相同,还增加了 "**" 表示 "此目录以及所有子目录,递归"。 换句话说,它启用递归通配:

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

此方法会在顶层目录上调用 Path.is_dir() 并传播所引发的任何 OSError 异常。扫描目录时产生的后续 OSError 异常则会被抑制。

在默认情况下,或当 case_sensitive 关键字参数被设为 None 时,该方法将使用特定平台的大小写规则匹配路径:通常,在 POSIX 上区分大小写,而在 Windows 上不区分大小写。将 case_sensitive 设为 True 或 False 可覆盖此行为。

备注

在一个较大的目录树中使用 "**" 模式可能会消耗非常多的时间。

引发一个 审计事件 pathlib.Path.glob 并附带参数 self, pattern。

在 3.11 版本发生变更: 如果 pattern 以一个路径名称部分的分隔符结束 (sep 或 altsep) 则只返回目录。

在 3.12 版本发生变更: 增加了 case_sensitive 形参。

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

递归地对给定的相对 pattern 执行 glob 通配。 这类似于调用 Path.glob() 时在 pattern 之前加上 "**/",其中 patterns 的形式与 fnmatch 的相同:

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

在默认情况下,或当 case_sensitive 关键字参数被设为 None 时,该方法将使用特定平台的大小写规则匹配路径:通常,在 POSIX 上区分大小写,而在 Windows 上不区分大小写。将 case_sensitive 设为 True 或 False 可覆盖此行为。

引发一个 审计事件 pathlib.Path.rglob 并附带参数 self, pattern。

在 3.11 版本发生变更: 如果 pattern 以一个路径名称部分的分隔符结束 (sep 或 altsep) 则只返回目录。

在 3.12 版本发生变更: 增加了 case_sensitive 形参。

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

通过对目录树自上而下或自下而上的遍历来生成其中的文件名。

对于根位置为 self 的目录树中的每个目录(包括 self 但不包括 '.' 和 '..'),该方法会产生一个 3 元组 (dirpath, dirnames, filenames)。

dirpath 是指向当前正被遍历到的目录的 Path,dirnames 是由表示 dirpath 中子目录名称的字符串组成的列表 (不包括 '.' 和 '..'),filenames 是由表示 dirpath 中非目录文件名称的字符串组成的列表。 要获取 dirpath 中文件或目录的完整路径 (以 self 开头),可使用 dirpath / name。 这些列表是否排序取决于具体的文件系统。

如果可选参数 top_down 为(默认的)真值,则会在所有子目录的三元组生成之前生成父目录的三元组(目录是自上而下遍历的)。 如果 top_down 为假值,则会在所有子目录的三元组生成之后再生成父目录的三元组(目录是是自下而上遍历的)。无论 top_down 的值是什么,都会在遍历目录及其子目录的三元组之前提取子目录列表。

当 top_down 为真值时,调用方可以原地修改 dirnames 列表(例如,使用 del 或切片赋值),而 Path.walk() 只会向名称保留在 dirnames 中的子目录递归。 这可被用于搜索剪枝,或强制应用特定的访问顺序,或者甚至是在重新恢复执行 Path.walk() 之前告知 Path.walk() 调用方所创建或重命名的目录。 当 top_down 为假值时修改 dirnames 不会对 Path.walk() 的的行为造成影响,因为在 dirnames 被提供给调用方时 dirnames 中的目录已经被生成了。

在默认情况下,来自 os.scandir() 的错误将被忽略。 如果指定了可选参数 on_error,则它应为一个可调用对象;调用它需要传入一个参数,即 OSError 的实例。 该可调用对象能处理错误以继续执行遍历或是重新引发错误以停止遍历。 请注意可以通过异常对象的 filename 属性来获取文件名。

在默认情况下,Path.walk() 不会跟踪符号链接,而是将其添加到 filenames 列表中。 将 follow_symlinks 设为真值可解析符号链接并根据它们的目标将其放入 dirnames 和 filenames 中,从而(在受支持的系统上)访问符号链接所指向的目录。

备注

请注意将 follow_symlinks 设为真值会在链接指向自身的父目录时导致无限递归。 Path.walk() 不会跟踪已它访问过的目录。

备注

Path.walk() 会假定在执行过程中它所遍历的目录没有被修改。 例如,如果 dirnames 中的某个目录已被替换为符号链接并且 follow_symlinks 为假值,则 Path.walk() 仍会尝试进入该目录。 为防止出现这种行为,请相应地移除 dirnames 中的目录。

备注

与 os.walk() 不同,当 follow_symlinks 为假值时 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() 不允许在目录为空之前删除该目录因此自下而上地遍历目录树是至关重要的:

# 删除可从目录 "top" 进入的所有东西。
# 小心:这很危险!举例来说,如果 top == Path('/'),
# 它可能会删除你的全部文件。
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.

创建文件和目录

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

使用给定的路径创建文件。 如果给出了 mode,它将与进程的 umask 值合并以确定文件模式和访问旗标。 如果文件已存在,则当 exist_ok 为真值时函数将成功执行(并且其修改时间将更新为当前时间),在其他情况下则会引发 FileExistsError。

参见

open(), write_text() 和 write_bytes() 方法经常被用来创建文件。

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

使用给定的路径新建目录。 如果给出了 mode,它将与进程的 umask 值合并来决定文件模式和访问旗标。 如果路径已存在,则会引发 FileExistsError。

如果 parents 为真值,任何找不到的父目录都会伴随着此路径被创建;它们会以默认权限被创建,而不考虑 mode 设置(模仿 POSIX 的 mkdir -p 命令)。

如果 parents 为假值(默认),则找不到的父级目录会引发 FileNotFoundError。

如果 exist_ok 为 false(默认),则在目标已存在的情况下抛出 FileExistsError。

如果 exist_ok 为真值,则 FileExistsError 将不会被引发除非给定的路径在文件系统中已存在并且不是目录(与 POSIX mkdir -p 命令的行为相同)。

在 3.5 版本发生变更: exist_ok 形参被加入。

使该路径成为一个指向 target 的符号连接。

在 Windows,符号链接可以代表文件或者目录,并且不会动态适应目标。 如果目标存在,则将创建相匹配的符号链接类型。 在其他情况下,如果 target_is_directory 为真值则符号链接将创建为目录类型否则将创建为文件符号链接。 在非 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() 是相反的。

将此路径设为一个指向与 target 相同文件的硬链接。

备注

参数顺序 (link, target) 和 os.link() 是相反的。

Added in version 3.10.

重命名与删除

Path.rename(target)

将此文件或目录重命名为给定的 target,并返回一个新的指向 target 的 Path 实例。 在 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.rmdir() 代替。

如果 missing_ok 为假值(默认),则如果路径不存在将会引发 FileNotFoundError。

如果 missing_ok 为真值,则 FileNotFoundError 异常将被忽略(和 POSIX rm -f 命令的行为相同)。

在 3.8 版本发生变更: 增加了 missing_ok 形参。

Path.rmdir()

移除此目录。此目录必须为空的。

访问权限与所有权

Path.owner()

返回拥有此文件的用户名。 如果文件的用户标识符 (UID) 无法在系统数据库中找到则会引发 KeyError。

Path.group()

返回拥有此文件的用户组名。 如果文件的用户组标识符 (GID) 无法在系统数据库中找到则会引发 KeyError。

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

改变文件模式和权限,和 os.chmod() 一样。

此方法通常会跟随符号链接。 某些 Unix 变种支持改变 symlink 本身的权限;在这些平台上你可以添加参数 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() 但是如果路径指向符号链接则是修改符号链接的模式,而不是修改符号链接的目标。

对应的 os 模块的工具

以下是一个映射了 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()

备注