11.1. pathlib
— 面向对象的文件系统路径¶
3.4版本新增.
源码: Lib/pathlib.py
本模块提供适合于不同操作系统的类来对文件系统路径进行操作。路径类在pure paths和concrete paths之间划分,它提供纯粹的计算操作,而不是I / O,它继承纯路径,但也提供I / O操作。
如果您以前从未使用过此模块,或者只是不确定哪个类适合您的任务,则pathlib
很有可能是您需要的。它为代码运行的平台实例化一个concrete path。
在某些特殊情况下,Pure paths非常有用,例如:
- 如果你想在Unix机器上操作Windows路径(反之亦然)。在Unix上运行时,不能实例化
WindowsPath
,但可以实例化PureWindowsPath
。 - 您希望确保您的代码只操作路径而不实际访问操作系统。在这种情况下,实例化纯类之一可能是有用的,因为那些简单地没有任何OS访问操作。
注意
This module has been included in the standard library on a provisional basis. 如果核心开发者认为有必要,可能会发生向后不兼容的更改(直到并包括删除程序包)。
也可以看看
PEP 428:pathlib模块 - 面向对象的文件系统路径。
也可以看看
对于字符串的低级别路径处理,您还可以使用os.path
模块。
11.1.1.基本使用¶
导入主类:
>>> 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'
11.1.2.纯路径¶
纯路径对象提供实际上不访问文件系统的路径处理操作。有三种方法来访问这些类,我们也称为flavors:
- class
pathlib.
PurePath
(*pathsegments)¶ 表示系统的路径风格(实例化它创建
PurePosixPath
或PureWindowsPath
)的通用类:>>> PurePath('setup.py') # Running on a Unix machine PurePosixPath('setup.py')
pathsegments的每个元素可以是表示路径段的字符串,也可以是其他路径对象:
>>> 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')
虚线斜线和单个点折叠,但双点(
'..'
)不是,因为这将改变符号链接面的路径的含义:>>> PurePath('foo//bar') PurePosixPath('foo/bar') >>> PurePath('foo/./bar') PurePosixPath('foo/bar') >>> PurePath('foo/../bar') PurePosixPath('foo/../bar')
(一个朴素的方法会使
PurePosixPath('foo/../bar')
等效于PurePosixPath('bar')
,如果foo
- class
pathlib.
PurePosixPath
(*pathsegments)¶ PurePath
的子类,此路径flavor表示非Windows文件系统路径:>>> PurePosixPath('/etc') PurePosixPath('/etc')
pathsegments与
PurePath
类似地指定。
- class
pathlib.
PureWindowsPath
(*pathsegments)¶ PurePath
的子类,此路径flavor表示Windows文件系统路径:>>> PureWindowsPath('c:/Program Files/') PureWindowsPath('c:/Program Files')
pathsegments与
PurePath
类似地指定。
无论您正在运行的系统如何,都可以实例化所有这些类,因为它们不提供任何执行系统调用的操作。
11.1.2.1.一般属性¶
路径是不可变的和哈希的。相同味道的路径是可比较和有序的。这些属性尊重风格的case-folding语义:
>>> 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: unorderable types: PureWindowsPath() < PurePosixPath()
11.1.2.2.运算符¶
slash操作符号有助于创建子路径,类似于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')
路径的字符串表示是原始文件系统路径本身(以原生形式,例如,在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形式是文件系统路径的规范表示。
11.1.2.3.访问各个部分¶
要访问路径的各个“parts”(组件),请使用以下属性:
PurePath.
parts
¶可以访问路径各个组件的元组:
>>> p = PurePath('/usr/bin/python3') >>> p.parts ('/', 'usr', 'bin', 'python3') >>> p = PureWindowsPath('c:/Program Files/PSF') >>> p.parts ('c:\\', 'Program Files', 'PSF')
(请注意驱动器和本地根在单个部分中如何重新分组)
11.1.2.4.方法和属性¶
纯路径提供以下方法和属性:
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 '\\'
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:/')
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'
>>> 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
()¶返回路径是否为绝对路径。如果路径同时具有根和(如果flavor允许)驱动器,则路径被视为绝对路径:
>>> 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_reserved
()¶如果
PureWindowsPath
,则返回True
如果路径在Windows下被视为保留,则False
使用PurePosixPath
,始终返回False
。>>> PureWindowsPath('nul').is_reserved() True >>> PurePosixPath('nul').is_reserved() False
保留路径上的文件系统调用可能会神秘失败或产生意外的影响。
PurePath.
joinpath
(*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)¶将此路径与提供的glob样式模式匹配。如果匹配成功,返回
True
,否则返回False
。如果模式是相对的,则路径可以是相对的或绝对的,并且从右侧进行匹配:
>>> 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
如果模式是绝对路径,则路径必须是绝对路径,并且整个路径必须匹配:
>>> PurePath('/a.py').match('/*.py') True >>> PurePath('a/b.py').match('/*.py') False
与其他方法一样,观察到区分大小写:
>>> PureWindowsPath('b.py').match('*.PY') True
PurePath.
relative_to
(*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' does not start with '/usr'
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
11.1.3.具体路径¶
具体路径是纯路径类的子类。除了后者提供的操作之外,它们还提供了对路径对象进行系统调用的方法。有三种方法来实例化具体路径:
- class
pathlib.
Path
(*pathsegments)¶ PurePath
的子类,此类表示系统的路径flavor的具体路径(实例化它创建PosixPath
或WindowsPath
):>>> Path('setup.py') PosixPath('setup.py')
pathsegments与
PurePath
类似地指定。
- class
pathlib.
PosixPath
(*pathsegments)¶ Path
和PurePosixPath
的子类,此类表示具体的非Windows文件系统路径:>>> PosixPath('/etc') PosixPath('/etc')
pathsegments与
PurePath
类似地指定。
- class
pathlib.
WindowsPath
(*pathsegments)¶ Path
和PureWindowsPath
的子类,此类表示具体的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
11.1.3.1.方法¶
除了纯路径方法之外,具体路径还提供以下方法。如果系统调用失败(例如因为路径不存在),这些方法中的许多可以引发OSError
:
- classmethod
Path.
cwd
()¶ 返回表示当前目录的新路径对象(由
os.getcwd()
返回):>>> Path.cwd() PosixPath('/home/antoine/pathlib')
- classmethod
Path.
home
()¶ 返回表示用户主目录(由
os.path.expanduser()
返回的~
构造)的新路径对象:>>> Path.home() PosixPath('/home/antoine')
版本3.5中的新功能。
Path.
stat
()¶返回有关此路径的信息(类似于
os.stat()
)。在每次调用此方法时查找结果。>>> p = Path('setup.py') >>> p.stat().st_size 956 >>> p.stat().st_mtime 1327883547.852554
Path.
chmod
(mode)¶更改文件模式和权限,如
os.chmod()
:>>> p = Path('setup.py') >>> p.stat().st_mode 33277 >>> p.chmod(0o444) >>> p.stat().st_mode 33060
Path.
exists
()¶路径是否指向现有文件或目录:
>>> Path('.').exists() True >>> Path('setup.py').exists() True >>> Path('/etc').exists() True >>> Path('nonexistentfile').exists() False
注意
如果路径指向符号链接,
exists()
返回符号链接是否指向现有文件或目录。
Path.
expanduser
()¶返回由
os.path.expanduser()
返回的扩展~
和~user
构造的新路径:>>> p = PosixPath('~/films/Monty Python') >>> p.expanduser() PosixPath('/home/eric/films/Monty Python')
版本3.5中的新功能。
Path.
glob
(pattern)¶将此路径表示的目录中给定的模式全局化,生成所有匹配的文件(任何类型):
>>> sorted(Path('.').glob('*.py')) [PosixPath('pathlib.py'), PosixPath('setup.py'), PosixPath('test_pathlib.py')] >>> sorted(Path('.').glob('*/*.py')) [PosixPath('docs/conf.py')]
“
**
”模式表示“此目录和所有子目录,递归”。换句话说,它启用递归globbing:>>> 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
()¶如果路径指向目录(或指向目录的符号链接),则返回
True
,如果它指向另一种文件,则返回False
。False
也会在路径不存在或断开的符号链接时返回;其他错误(例如权限错误)被传播。
Path.
is_file
()¶如果路径指向常规文件(或指向常规文件的符号链接),则返回
True
,如果它指向另一种文件,则返回False
。False
也会在路径不存在或断开的符号链接时返回;其他错误(例如权限错误)被传播。
Path.
is_symlink
()¶如果路径指向符号链接,则返回
True
,否则返回False
。False
也会在路径不存在时返回;其他错误(例如权限错误)被传播。
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.
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')
Path.
lchmod
(mode)¶像
Path.chmod()
,但是,如果路径指向符号链接,符号链接的模式将更改,而不是其目标。
Path.
lstat
()¶像
Path.stat()
,但是,如果路径指向符号链接,则返回符号链接的信息,而不是其目标。
Path.
mkdir
(mode=0o777, parents=False, exist_ok=False)¶在此给定路径创建一个新目录。如果给出模式,则将其与进程“
umask
值组合以确定文件模式和访问标志。如果路径已存在,则会引发FileExistsError
。如果parents为真,则根据需要创建此路径的任何缺少的父项;它们是使用默认权限创建的,而不考虑模式(模仿POSIX
mkdir -p
命令)。如果parents为false(默认值),则缺少父引用
FileNotFoundError
。如果exists_ok为false(默认值),则如果目标目录已存在,则会引发
FileExistsError
。如果exists_ok为真,则会忽略
FileExistsError
异常(与POSIXmkdir -p
命令),但前提是最后一个路径组件不是现有的非目录文件。在版本3.5中已更改:添加了exists_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.
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中的新功能。
Path.
rename
(target)¶将此文件或目录重命名为给定的目标。在Unix上,如果目标存在并且是文件,如果用户具有权限,则将以静默方式替换。target可以是字符串或另一个路径对象:
>>> p = Path('foo') >>> p.open('w').write('some text') 9 >>> target = Path('bar') >>> p.rename(target) >>> target.open().read() 'some text'
Path.
replace
(target)¶将此文件或目录重命名为给定的目标。如果target指向现有文件或目录,它将被无条件替换。
Path.
resolve
()¶使路径为绝对路径,解析任何符号链接。返回一个新的路径对象:
>>> p = Path() >>> p PosixPath('.') >>> p.resolve() PosixPath('/home/antoine/pathlib')
“..”组件也被删除(这是唯一的方法):
>>> p = Path('docs/../setup.py') >>> p.resolve() PosixPath('/home/antoine/pathlib/setup.py')
如果路径不存在,则会引发
FileNotFoundError
。如果沿解析路径遇到无限循环,则会引发RuntimeError
。
Path.
rglob
(pattern)¶这就像在给定的模式前添加“
**
”调用glob()
>>> sorted(Path().rglob("*.py")) [PosixPath('build/lib/pathlib.py'), PosixPath('docs/conf.py'), PosixPath('pathlib.py'), PosixPath('setup.py'), PosixPath('test_pathlib.py')]
Path.
rmdir
()¶删除此目录。该目录必须为空。
Path.
samefile
(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.
symlink_to
(target, target_is_directory=False)¶将此路径作为目标的符号链接。在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()
的顺序相反。
Path.
touch
(mode=0o666, exist_ok=True)¶在此给定路径创建一个文件。如果给出模式,则将其与进程“
umask
值组合以确定文件模式和访问标志。如果文件已经存在,则如果exists_ok为真(并且其修改时间更新为当前时间),则函数将成功,否则会引发FileExistsError
。
Path.
unlink
()¶删除此文件或符号链接。如果路径指向目录,请改用
Path.rmdir()
。
Path.
write_bytes
(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)¶在文本模式下打开指向的文件,向其写入数据,然后关闭文件:
>>> p = Path('my_text_file') >>> p.write_text('Text file contents') 18 >>> p.read_text() 'Text file contents'
版本3.5中的新功能。