pathlib
— 面向对象的⽂件系统路径¶
3.4 版本新增。
源代码: Lib/pathlib/
此模块提供了表示文件系统路径的类,这些类具有适用于不同操作系统的语义。路径类分为纯路径(提供纯计算操作,不涉及 I/O)和具体路径(继承自纯路径,但也提供 I/O 操作)。
如果您以前从未使用过此模块,或者不确定哪个类适合您的任务,那么 Path
很可能是您所需要的。它会为代码运行的平台实例化一个具体路径。
纯路径在某些特殊情况下很有用;例如
如果您想在 Unix 机器上操作 Windows 路径(或反之亦然)。在 Unix 上运行时,您无法实例化
WindowsPath
,但可以实例化PureWindowsPath
。您想确保您的代码仅操作路径,而不实际访问操作系统。在这种情况下,实例化纯类之一可能很有用,因为这些类根本没有任何操作系统访问操作。
另请参阅
PEP 428: pathlib 模块 – 面向对象的⽂件系统路径。
另请参阅
对于字符串上的底层路径操作,您还可以使用 os.path
模块。
基本用法¶
导入主类
>>> from pathlib import Path
列出子目录
>>> p = Path('.')
>>> [x for x in p.iterdir() if x.is_dir()]
[PosixPath('.hg'), PosixPath('docs'), PosixPath('dist'),
PosixPath('__pycache__'), PosixPath('build')]
列出此目录树中的 Python 源代码文件
>>> list(p.glob('**/*.py'))
[PosixPath('test_pathlib.py'), PosixPath('setup.py'),
PosixPath('pathlib.py'), PosixPath('docs/conf.py'),
PosixPath('build/lib/pathlib.py')]
在目录树内导航
>>> p = Path('/etc')
>>> q = p / 'init.d' / 'reboot'
>>> q
PosixPath('/etc/init.d/reboot')
>>> q.resolve()
PosixPath('/etc/rc.d/init.d/halt')
查询路径属性
>>> q.exists()
True
>>> q.is_dir()
False
打开文件
>>> with q.open() as f: f.readline()
...
'#!/bin/bash\n'
异常¶
- exception pathlib.UnsupportedOperation¶
当在路径对象上调用不支持的操作时,引发的继承
NotImplementedError
的异常。3.13 版本新增。
纯路径¶
纯路径对象提供路径处理操作,而这些操作实际上不会访问文件系统。有三种方式可以访问这些类,我们也将它们称为风味
- 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'
)时,不会重置驱动器>>> 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')
(一种幼稚的方法会使
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 路径>>> PureWindowsPath('c:/', 'Users', 'Ximénez') PureWindowsPath('c:/Users/Ximénez') >>> 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()
。如果参数是绝对路径,则忽略先前的路径。在 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*,段落 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¶
一个不可变的序列,提供对路径的逻辑祖先的访问
>>> 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 版本中更改: 父序列现在支持 切片 和负索引值。
- PurePath.parent¶
路径的逻辑父级
>>> p = PurePosixPath('/a/b/c/d') >>> p.parent PurePosixPath('/a/b/c')
您不能超过锚点或空路径
>>> 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.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 版本中添加。
自 3.12 版本起弃用,将在 3.14 版本中删除: 传递附加参数已弃用;如果提供,它们将与 *other* 连接。
- PurePath.is_reserved()¶
使用
PureWindowsPath
,如果路径在 Windows 下被认为是保留的,则返回True
,否则返回False
。使用PurePosixPath
,始终返回False
。在 3.13 版本中更改: 包含冒号或以点或空格结尾的 Windows 路径名被认为是保留的。UNC 路径可能是保留的。
自 3.13 版本起弃用,将在 3.15 版本中删除: 此方法已弃用;使用
os.path.isreserved()
检测 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)¶
将此路径与提供的 glob 样式模式进行匹配。如果匹配成功,则返回
True
,否则返回False
。例如>>> 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
另请参阅
模式语言 文档。
与其他方法一样,大小写敏感性遵循平台默认值
>>> 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)¶
将此路径与提供的非递归 glob 风格模式进行匹配。如果匹配成功,则返回
True
,否则返回False
。此方法类似于
full_match()
,但不允许使用空模式(会引发ValueError
),不支持递归通配符“**
”(它的作用类似于非递归的“*
”),并且如果提供了相对模式,则匹配将从右侧开始。>>> 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 版本中变更: pattern 参数接受一个 路径类对象。
在 3.12 版本中变更: 添加了 case_sensitive 参数。
- PurePath.relative_to(other, walk_up=False)¶
计算此路径相对于 other 所代表的路径的版本。如果不可能,则引发
ValueError
。>>> p = PurePosixPath('/etc/passwd') >>> p.relative_to('/') PurePosixPath('etc/passwd') >>> p.relative_to('/etc') PurePosixPath('passwd') >>> p.relative_to('/usr') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "pathlib.py", line 941, in relative_to raise ValueError(error_message.format(str(self), str(formatted))) ValueError: '/etc/passwd' is not in the subpath of '/usr' OR one path is relative and the other is absolute.
当 walk_up 为 false(默认值)时,路径必须以 other 开头。当此参数为 true 时,可以添加
..
条目以形成相对路径。在所有其他情况下,例如路径引用不同的驱动器,则会引发ValueError
。>>> p.relative_to('/usr', walk_up=True) PurePosixPath('../etc/passwd') >>> p.relative_to('foo', walk_up=True) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "pathlib.py", line 941, in relative_to raise ValueError(error_message.format(str(self), str(formatted))) ValueError: '/etc/passwd' is not on the same drive as 'foo' OR one path is relative and the other is absolute.
警告
此函数是
PurePath
的一部分,并且可以处理字符串。它不会检查或访问底层文件结构。这会影响 walk_up 选项,因为它假设路径中不存在符号链接;如有必要,请先调用resolve()
来解析符号链接。在 3.12 版本中变更: 添加了 walk_up 参数(旧行为与
walk_up=False
相同)。自 3.12 版本起弃用,将在 3.14 版本中移除: 传递额外的 positional 参数已弃用;如果提供,它们将与 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
已更改的新路径。如果原始路径没有 name,则会引发 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 版本中变更: 在 Windows 上引发
UnsupportedOperation
。在以前的版本中,则会引发NotImplementedError
。
- class pathlib.WindowsPath(*pathsegments)¶
作为
Path
和PureWindowsPath
的子类,此类表示具体的 Windows 文件系统路径。>>> WindowsPath('c:/', 'Users', 'Ximénez') WindowsPath('c:/Users/Ximénez')
pathsegments 的指定方式类似于
PurePath
。在 3.13 版本中变更: 在非 Windows 平台上引发
UnsupportedOperation
。在以前的版本中,则会引发NotImplementedError
。
您只能实例化与您的系统对应的类风格(允许对不兼容的路径风格进行系统调用可能会导致应用程序中出现错误或失败)。
>>> 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
。
解析和生成 URI¶
具体路径对象可以从符合 RFC 8089 的“文件”URI 创建,并表示为“文件”URI。
注意
文件 URI 在具有不同 文件系统编码 的机器之间不可移植。
- classmethod Path.from_uri(uri)¶
从解析“文件”URI 返回一个新的路径对象。例如
>>> p = Path.from_uri('file:///etc/hosts') PosixPath('/etc/hosts')
在 Windows 上,可以从 URI 解析 DOS 设备和 UNC 路径。
>>> p = Path.from_uri('file:///c:/windows') WindowsPath('c:/windows') >>> 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://///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')
如果 URI 不是以
file:
开头,或者解析的路径不是绝对路径,则会引发ValueError
。3.13 版本新增。
- Path.as_uri()¶
将路径表示为“文件”URI。如果路径不是绝对路径,则会引发
ValueError
。>>> p = PosixPath('/etc/passwd') >>> p.as_uri() 'file:///etc/passwd' >>> p = WindowsPath('c:/Windows') >>> p.as_uri() 'file:///c:/Windows'
出于历史原因,此方法也可从
PurePath
对象访问。但是,它对os.fsencode()
的使用使其成为严格意义上的不纯方法。
展开和解析路径¶
- 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')
如果路径不存在或遇到符号链接循环,并且 strict 为
True
,则会引发OSError
。如果 strict 为False
,则会尽可能解析路径,并将任何剩余部分附加到路径末尾,而不检查其是否存在。在 3.6 版本中更改: 添加了 strict 参数(3.6 之前的行为是严格的)。
在 3.13 版本中更改: 符号链接循环被视为其他错误:在严格模式下会引发
OSError
,而在非严格模式下不会引发异常。在之前的版本中,无论 strict 的值如何,都会引发RuntimeError
。
- Path.readlink()¶
返回符号链接指向的路径(由
os.readlink()
返回)>>> p = Path('mylink') >>> p.symlink_to('setup.py') >>> p.readlink() PosixPath('setup.py')
在 3.9 版本中添加。
在 3.13 版本中更改: 如果
os.readlink()
不可用,则引发UnsupportedOperation
。在之前的版本中,会引发NotImplementedError
。
查询文件类型和状态¶
在 3.8 版本中更改: 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()
。每次调用此方法时都会查找结果。此方法通常会跟随符号链接;要统计符号链接,请添加参数
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)¶
如果路径指向常规文件,则返回
True
,如果路径指向另一种类型的文件,则返回False
。如果路径不存在或是断开的符号链接,也会返回
False
;其他错误(例如权限错误)会传播。此方法通常会跟随符号链接;要排除符号链接,请添加参数
follow_symlinks=False
。在 3.13 版本中更改: 添加了 follow_symlinks 参数。
- Path.is_dir(*, follow_symlinks=True)¶
如果路径指向目录,则返回
True
,如果路径指向另一种类型的文件,则返回False
。如果路径不存在或是断开的符号链接,也会返回
False
;其他错误(例如权限错误)会传播。此方法通常会跟随符号链接;要排除指向目录的符号链接,请添加参数
follow_symlinks=False
。在 3.13 版本中更改: 添加了 follow_symlinks 参数。
- Path.is_symlink()¶
如果路径指向符号链接,则返回
True
,否则返回False
。如果路径不存在,也会返回
False
;其他错误(例如权限错误)会传播。
- Path.is_junction()¶
如果路径指向连接点,则返回
True
,对于任何其他类型的文件,则返回False
。目前只有 Windows 支持连接点。在 3.12 版本中添加。
- Path.is_mount()¶
如果路径是挂载点,则返回
True
:文件系统中挂载了不同文件系统的点。在 POSIX 系统上,此函数检查 *path* 的父目录,即path/..
,是否与 *path* 位于不同的设备上,或者path/..
和 *path* 是否指向同一设备上的相同 i-node——这应该可以检测所有 Unix 和 POSIX 变体的挂载点。在 Windows 系统上,挂载点被视为驱动器盘符根目录(例如c:\
)、UNC 共享(例如\\server\share
)或已挂载的文件系统目录。在 3.7 版本中添加。
在 3.12 版本中更改: 添加了 Windows 支持。
- Path.is_socket()¶
如果路径指向 Unix 套接字(或指向 Unix 套接字的符号链接),则返回
True
,如果指向其他类型的文件,则返回False
。如果路径不存在或是断开的符号链接,也会返回
False
;其他错误(例如权限错误)会传播。
- Path.is_fifo()¶
如果路径指向 FIFO(或指向 FIFO 的符号链接),则返回
True
,如果指向其他类型的文件,则返回False
。如果路径不存在或是断开的符号链接,也会返回
False
;其他错误(例如权限错误)会传播。
- Path.is_block_device()¶
如果路径指向块设备(或指向块设备的符号链接),则返回
True
,如果指向其他类型的文件,则返回False
。如果路径不存在或是断开的符号链接,也会返回
False
;其他错误(例如权限错误)会传播。
- Path.is_char_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 版本新增。
读取和写入文件¶
- 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()¶
当路径指向目录时,生成目录内容的路径对象
>>> 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, recurse_symlinks=False)¶
在由此路径表示的目录中,使用给定的相对 *pattern* 进行 glob 匹配,生成所有匹配的文件(任何类型的)
>>> 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')]
另请参阅
模式语言 文档。
默认情况下,或者当仅关键字参数 *case_sensitive* 设置为
None
时,此方法使用平台特定的区分大小写规则匹配路径:通常在 POSIX 上区分大小写,在 Windows 上不区分大小写。将 *case_sensitive* 设置为True
或False
可覆盖此行为。默认情况下,或者当仅关键字参数 *recurse_symlinks* 设置为
False
时,此方法遵循符号链接,但在展开“**
”通配符时除外。将 *recurse_symlinks* 设置为True
可始终遵循符号链接。使用参数
self
、pattern
引发 审核事件pathlib.Path.glob
。在 3.12 版本中变更: 添加了 case_sensitive 参数。
在 3.13 版本中更改: 添加了 *recurse_symlinks* 参数。
在 3.13 版本中更改: *pattern* 参数接受 类路径对象。
在 3.13 版本中变更: 扫描文件系统时引发的任何
OSError
异常都会被抑制。在之前的版本中,此类异常在许多情况下会被抑制,但并非所有情况都如此。
- Path.rglob(pattern, *, case_sensitive=None, recurse_symlinks=False)¶
递归地匹配给定的相对 pattern 模式。 这类似于调用
Path.glob()
并在 pattern 前面添加 “**/
”。另请参阅
模式语言 和
Path.glob()
文档。引发一个带有参数
self
,pattern
的 审计事件pathlib.Path.rglob
。在 3.12 版本中变更: 添加了 case_sensitive 参数。
在 3.13 版本中更改: 添加了 *recurse_symlinks* 参数。
在 3.13 版本中更改: *pattern* 参数接受 类路径对象。
- 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 为 true(默认值),则在生成任何子目录的三元组之前,会先生成目录的三元组(目录会自顶向下遍历)。 如果 top_down 为 false,则会在生成所有子目录的三元组之后生成目录的三元组(目录会自底向上遍历)。 无论 top_down 的值如何,都会在遍历目录及其子目录的三元组之前检索子目录的列表。
当 top_down 为 true 时,调用者可以就地修改 dirnames 列表(例如,使用
del
或切片赋值),并且Path.walk()
只会递归进入 dirnames 中保留名称的子目录。 这可用于修剪搜索范围、强制执行特定的访问顺序,甚至可以通知Path.walk()
调用者在它再次恢复Path.walk()
之前创建或重命名的目录。当 top_down 为 false 时修改 dirnames 对Path.walk()
的行为没有影响,因为 dirnames 中的目录在 dirnames 被返回给调用者时已经生成。默认情况下,来自
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 中删除目录。注意
与
os.walk()
不同,如果 follow_symlinks 为 false,则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
。另请参阅
open()
、write_text()
和write_bytes()
方法通常用于创建文件。
- 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
异常,除非给定的路径在文件系统中已存在且不是目录(行为与 POSIXmkdir -p
命令相同)。在 3.5 版本中更改: 添加了 exist_ok 参数。
- Path.symlink_to(target, target_is_directory=False)¶
将此路径创建为指向 target 的符号链接。
在 Windows 上,符号链接表示文件或目录,不会动态更改为目标。如果目标存在,则将创建与目标类型匹配的符号链接。否则,如果 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
注意
参数的顺序(链接,目标)与
os.symlink()
的顺序相反。在 3.13 版本中更改: 如果
os.symlink()
不可用,则引发UnsupportedOperation
。在之前的版本中,会引发NotImplementedError
。
- Path.hardlink_to(target)¶
将此路径创建为与 target 文件相同的硬链接。
注意
参数的顺序(链接,目标)与
os.link()
的顺序相反。在 3.10 版本中添加。
在 3.13 版本中更改: 如果
os.link()
不可用,则引发UnsupportedOperation
。在之前的版本中,会引发NotImplementedError
。
重命名和删除¶
- 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.unlink(missing_ok=False)¶
删除此文件或符号链接。如果路径指向目录,请改用
Path.rmdir()
。如果 missing_ok 为 false(默认值),如果路径不存在,则会引发
FileNotFoundError
异常。如果 missing_ok 为 true,则
FileNotFoundError
异常将被忽略(行为与 POSIXrm -f
命令相同)。在 3.8 版本中更改: 添加了 missing_ok 参数。
- Path.rmdir()¶
删除此目录。该目录必须为空。
权限和所有权¶
- Path.owner(*, follow_symlinks=True)¶
返回拥有该文件的用户的名称。如果在系统数据库中找不到该文件的用户标识 (UID),则会引发
KeyError
异常。此方法通常遵循符号链接;要获取符号链接的所有者,请添加参数
follow_symlinks=False
。在 3.13 版本中更改: 如果
pwd
模块不可用,则会引发UnsupportedOperation
。在早期版本中,会引发NotImplementedError
。在 3.13 版本中更改: 添加了 follow_symlinks 参数。
- Path.group(*, follow_symlinks=True)¶
返回拥有该文件的组的名称。如果在系统数据库中找不到该文件的组标识 (GID),则会引发
KeyError
异常。此方法通常遵循符号链接;要获取符号链接的组,请添加参数
follow_symlinks=False
。在 3.13 版本中更改: 如果
grp
模块不可用,则会引发UnsupportedOperation
。在早期版本中,会引发NotImplementedError
。在 3.13 版本中更改: 添加了 follow_symlinks 参数。
- Path.chmod(mode, *, follow_symlinks=True)¶
更改文件模式和权限,类似于
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()
,但是如果路径指向符号链接,则更改符号链接的模式,而不是其目标的模式。
模式语言¶
以下通配符在 full_match()
、glob()
和 rglob()
的模式中受支持
**
(整个段)匹配任意数量的文件或目录段,包括零个。
*
(整个段)匹配一个文件或目录段。
*
(段的一部分)匹配任意数量的非分隔符字符,包括零个。
?
匹配一个非分隔符字符。
[seq]
匹配 seq 中的一个字符。
[!seq]
匹配不在 seq 中的一个字符。
对于字面匹配,请将元字符放在方括号中。例如,"[?]"
匹配字符 "?"
。
“**
” 通配符启用递归 globbing。以下是一些示例:
模式 |
含义 |
---|---|
“ |
至少包含一个段的任何路径。 |
“ |
最后一个段以 “ |
“ |
以 “ |
“ |
以 “ |
注意
使用 “**
” 通配符进行 globbing 会访问树中的每个目录。大型目录树可能需要很长时间才能搜索。
3.13 版本更改: 使用以 “**
” 结尾的模式进行 globbing 会同时返回文件和目录。在之前的版本中,只返回目录。
在 Path.glob()
和 rglob()
中,可以在模式末尾添加斜杠,以便仅匹配目录。
与 glob
模块的比较¶
Path.glob()
和 Path.rglob()
接受的模式和生成的结果与 glob
模块略有不同。
在 pathlib 中,以点开头的文件不是特殊的。这类似于向
glob.glob()
传递include_hidden=True
。“
**
” 模式组件在 pathlib 中始终是递归的。这类似于向glob.glob()
传递recursive=True
。默认情况下,pathlib 中的 “
**
” 模式组件不遵循符号链接。此行为在glob.glob()
中没有等效项,但您可以向Path.glob()
传递recurse_symlinks=True
以获得兼容的行为。与所有
PurePath
和Path
对象一样,从Path.glob()
和Path.rglob()
返回的值不包含尾部斜杠。与
glob.glob(root_dir=path)
的结果不同,pathlib 的path.glob()
和path.rglob()
返回的值包含 *path* 作为前缀。pathlib 的
path.glob()
和path.rglob()
返回的值可能包含 *path* 本身,例如在 globbing “**
” 时,而glob.glob(root_dir=path)
的结果永远不包含对应于 *path* 的空字符串。
与 os
和 os.path
模块的比较¶
pathlib 使用 PurePath
和 Path
对象实现路径操作,因此被称为是*面向对象*的。另一方面,os
和 os.path
模块提供使用底层 str
和 bytes
对象工作的函数,这是一种更*过程化*的方法。一些用户认为面向对象风格更具可读性。
os
和 os.path
中的许多函数都支持 bytes
路径和 相对于目录描述符的路径。这些功能在 pathlib 中不可用。
Python 的 str
和 bytes
类型以及 os
和 os.path
模块的部分是用 C 编写的,速度非常快。 pathlib 是用纯 Python 编写的,通常速度较慢,但很少慢到需要关注。
pathlib 的路径规范化比 os.path
稍微更主观和一致。例如,os.path.abspath()
从路径中删除 “..
” 段,如果涉及符号链接,可能会改变其含义,而 Path.absolute()
保留这些段以提高安全性。
pathlib 的路径规范化可能使其不适用于某些应用程序。
pathlib 将
Path("my_folder/")
规范化为Path("my_folder")
,当提供给各种操作系统 API 和命令行实用程序时,这会改变路径的含义。具体来说,缺少尾部分隔符可能会允许将路径解析为文件或目录,而不仅仅是目录。pathlib 将
Path("./my_program")
规范化为Path("my_program")
,当用作可执行搜索路径(例如在 shell 中或生成子进程时)时,这会改变路径的含义。具体来说,路径中缺少分隔符可能会强制在PATH
中查找它,而不是在当前目录中查找。
由于这些差异,pathlib 不能直接替代 os.path
。
相应的工具¶
下面是一个表,将各种 os
函数映射到它们对应的 PurePath
/Path
等效项。
脚注