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

3.4 新版功能.

源代码 Lib/pathlib.py


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

../_images/pathlib-inheritance.png

如果以前从未用过此模块,或不确定哪个类适合完成任务,那要用的可能就是 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')      # Running on a Unix machine
PurePosixPath('setup.py')

每一个 pathsegments 的元素可能是一个代表路径片段的字符串,一个返回字符串的实现了 os.PathLike 接口的对象,或者另一个路径对象:

>>> 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 路径中,改变本地根目录并不会丢弃之前盘符的设置:

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

Spurious slashes and single dots are collapsed, but double dots ('..') and leading double slashes ('//') are not, since this would change the meaning of a path for various reasons (e.g. symbolic links, UNC paths):

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

pathsegments 参数的指定和 PurePath 相同。

class pathlib.PureWindowsPath(*pathsegments)

A subclass of PurePath, this path flavour represents Windows filesystem paths, including UNC paths:

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

pathsegments 参数的指定和 PurePath 相同。

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

通用性质

路径是不可变并可哈希的。相同风格的路径可以排序与比较。这些性质尊重对应风格的大小写转换语义:

>>> 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() 一样:

>>> p = PurePath('/etc')
>>> p
PurePosixPath('/etc')
>>> p / 'init.d' / 'apache2'
PurePosixPath('/etc/init.d/apache2')
>>> q = PurePath('bin')
>>> '/usr' / q
PurePosixPath('/usr/bin')

文件对象可用于任何接受 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
'\\'

If the path starts with more than two successive slashes, PurePosixPath collapses them:

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

备注

This behavior conforms to The Open Group Base Specifications Issue 6, paragraph 4.11 Pathname Resolution:

“A pathname that begins with two successive slashes may be interpreted in an implementation-defined manner, although more than two leading slashes shall be treated as a single slash.”

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

An immutable sequence providing access to the logical ancestors of the path:

>>> 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 URL。如果并非绝对路径,抛出 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

3.9 新版功能.

PurePath.is_reserved()

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

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

当保留路径上的文件系统被调用,则可能出现玄学失败或者意料之外的效应。

PurePath.joinpath(*other)

调用此方法等同于将每个 other 参数中的项目连接在一起:

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

将此路径与提供的通配符风格的模式匹配。如果匹配成功则返回 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

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

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

计算此路径相对 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 694, in relative_to
    .format(str(self), str(formatted)))
ValueError: '/etc/passwd' is not in the subpath of '/usr' OR one path is relative and the other absolute.

注意:此函数是 PurePath 的一部分并且适用于字符串。 它不会检查或访问下层的文件结构。

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

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

具体路径

具体路径是纯路径的子类。除了后者提供的操作之外,它们还提供了对路径对象进行系统调用的方法。有三种方法可以实例化具体路径:

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 相同。

class pathlib.WindowsPath(*pathsegments)

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

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

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

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

classmethod Path.cwd()

返回一个新的表示当前目录的路径对象(和 os.getcwd() 返回的相同):

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

返回一个表示用户家目录的新路径对象(与带 ~ 构造的 os.path.expanduser() 所返回的相同)。 如果无法解析家目录,则会引发 RuntimeError

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

3.5 新版功能.

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

此路径是否指向一个已存在的文件或目录:

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

备注

如果路径指向一个符号链接, exists() 返回此符号链接是否指向存在的文件或目录。

Path.expanduser()

返回带有扩展 ~~user 构造的新路径,与 os.path.expanduser() 所返回的相同。 如果无法解析家目录,则会引发 RuntimeError

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

3.5 新版功能.

Path.glob(pattern)

解析相对于此路径的通配符 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')]

备注

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

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

在 3.11 版更改: Return only directories if pattern ends with a pathname components separator (sep or altsep).

Path.group()

返回拥有此文件的用户组。如果文件的 GID 无法在系统数据库中找到,将抛出 KeyError

Path.is_dir()

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

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

Path.is_file()

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

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

Path.is_mount()

Return True if the path is a mount point: a point in a file system where a different file system has been mounted. On POSIX, the function checks whether path’s parent, path/.., is on a different device than path, or whether path/.. and path point to the same i-node on the same device — this should detect mount points for all Unix and POSIX variants. On Windows, a mount point is considered to be a drive letter root (e.g. c:\), a UNC share (e.g. \\server\share), or a mounted filesystem directory.

3.7 新版功能.

在 3.12 版更改: Windows support was added.

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

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

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

The children are yielded in arbitrary order, and the special entries '.' and '..' are not included. If a file is removed from or added to the directory after creating the iterator, whether a path object for that file be included is unspecified.

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

Generate the file names in a directory tree by walking the tree either top-down or bottom-up.

For each directory in the directory tree rooted at self (including self but excluding ‘.’ and ‘..’), the method yields a 3-tuple of (dirpath, dirnames, filenames).

dirpath is a Path to the directory currently being walked, dirnames is a list of strings for the names of subdirectories in dirpath (excluding '.' and '..'), and filenames is a list of strings for the names of the non-directory files in dirpath. To get a full path (which begins with self) to a file or directory in dirpath, do dirpath / name. Whether or not the lists are sorted is file system-dependent.

If the optional argument top_down is true (which is the default), the triple for a directory is generated before the triples for any of its subdirectories (directories are walked top-down). If top_down is false, the triple for a directory is generated after the triples for all of its subdirectories (directories are walked bottom-up). No matter the value of top_down, the list of subdirectories is retrieved before the triples for the directory and its subdirectories are walked.

When top_down is true, the caller can modify the dirnames list in-place (for example, using del or slice assignment), and Path.walk() will only recurse into the subdirectories whose names remain in dirnames. This can be used to prune the search, or to impose a specific order of visiting, or even to inform Path.walk() about directories the caller creates or renames before it resumes Path.walk() again. Modifying dirnames when top_down is false has no effect on the behavior of Path.walk() since the directories in dirnames have already been generated by the time dirnames is yielded to the caller.

By default, errors from os.scandir() are ignored. If the optional argument on_error is specified, it should be a callable; it will be called with one argument, an OSError instance. The callable can handle the error to continue the walk or re-raise it to stop the walk. Note that the filename is available as the filename attribute of the exception object.

By default, Path.walk() does not follow symbolic links, and instead adds them to the filenames list. Set follow_symlinks to true to resolve symlinks and place them in dirnames and filenames as appropriate for their targets, and consequently visit directories pointed to by symlinks (where supported).

备注

Be aware that setting follow_symlinks to true can lead to infinite recursion if a link points to a parent directory of itself. Path.walk() does not keep track of the directories it has already visited.

备注

Path.walk() assumes the directories it walks are not modified during execution. For example, if a directory from dirnames has been replaced with a symlink and follow_symlinks is false, Path.walk() will still try to descend into it. To prevent such behavior, remove directories from dirnames as appropriate.

备注

Unlike os.walk(), Path.walk() lists symlinks to directories in filenames if follow_symlinks is false.

This example displays the number of bytes used by all files in each directory, while ignoring __pycache__ directories:

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

This next example is a simple implementation of shutil.rmtree(). Walking the tree bottom-up is essential as rmdir() doesn’t allow deleting a directory before it is empty:

# 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.lchmod(mode)

就像 Path.chmod() 但是如果路径指向符号链接则是修改符号链接的模式,而不是修改符号链接的目标。

Path.lstat()

就和 Path.stat() 一样,但是如果路径指向符号链接,则是返回符号链接而不是目标的信息。

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

新建给定路径的目录。如果给出了 mode ,它将与当前进程的 umask 值合并来决定文件模式和访问标志。如果路径已经存在,则抛出 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.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.owner()

返回拥有此文件的用户名。如果文件的 UID 无法在系统数据库中找到,则抛出 KeyError

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.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() 一样的可选形参。

3.5 新版功能.

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

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

3.9 新版功能.

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'

目标路径可能为绝对或相对路径。 相对路径将被解释为相对于当前工作目录,而 不是 相对于 Path 对象的目录。

在 3.8 版更改: 添加了返回值,返回新的 Path 实例。

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.

目标路径可能为绝对或相对路径。 相对路径将被解释为相对于当前工作目录,而 不是 相对于 Path 对象的目录。

在 3.8 版更改: 添加了返回值,返回新的 Path 实例。

Path.absolute()

Make the path absolute, without normalization or resolving symlinks. Returns a new path object:

>>> 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。如果 strictFalse,则路径将被尽可能地解析并且任何剩余部分都会被不检查是否存在地追加。如果在解析路径上发生无限循环,则抛出 RuntimeError

3.6 新版功能: 加入*strict* 参数(3.6之前的版本相当于strict值为True)

Path.rglob(pattern)

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

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

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

在 3.11 版更改: Return only directories if pattern ends with a pathname components separator (sep or altsep).

Path.rmdir()

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

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

3.5 新版功能.

将此路径创建为指向 target 的符号链接。在 Windows 下,如果链接的目标是一个目录则 target_is_directory 必须为 true (默认为 False)。在 POSIX 下, 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() 是相反的。

3.10 新版功能.

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

将给定的路径创建为文件。如果给出了 mode 它将与当前进程的 umask 值合并以确定文件的模式和访问标志。如果文件已经存在,则当 exist_ok 为 true 则函数仍会成功(并且将它的修改事件更新为当前事件),否则抛出 FileExistsError

移除此文件或符号链接。如果路径指向目录,则用 Path.rmdir() 代替。

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

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

在 3.8 版更改: 增加了 missing_ok 形参。

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.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 形参。

对应的 os 模块的工具

以下是一个映射了 osPurePath/Path 对应相同的函数的表。

备注

Not all pairs of functions/methods below are equivalent. Some of them, despite having some overlapping use-cases, have different semantics. They include os.path.abspath() and Path.absolute(), os.path.relpath() and PurePath.relative_to().

osos.path

pathlib

os.path.abspath()

Path.absolute() 1

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

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.stem and PurePath.suffix

备注

1

os.path.abspath() normalizes the resulting path, which may change its meaning in the presence of symlinks, while Path.absolute() does not.

2

PurePath.relative_to() requires self to be the subpath of the argument, but os.path.relpath() does not.