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

3.4 版新增。

此模块提供表示文件系统路径的类,采用适合不同操作系统的语义。路径类分为 纯路径 ,提供没有 I/O 的纯计算操作,和 具体路径 ,继承自纯路径但还提供 I/O 操作。

../_images/pathlib-inheritance.png

若之前从未用过此模块,或仅仅不确定哪个类适合任务, Path 更可能是您需要的。它实例化 具体路径 对于代码所运行的平台。

纯路径在某些特殊情况下很有用;例如:

  1. If you want to manipulate Windows paths on a Unix machine (or vice versa). You cannot instantiate a WindowsPath when running on Unix, but you can instantiate PureWindowsPath .
  2. You want to make sure that your code only manipulates paths without actually accessing the OS. In this case, instantiating one of the pure classes may be useful since those simply don’t have any OS-accessing operations.

注意

This module has been included in the standard library on a provisional basis . Backwards incompatible changes (up to and including removal of the package) may occur if deemed necessary by the core developers.

另请参阅

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. 纯路径

纯路径对象提供不实际访问文件系统的路径处理操作。访问这些类有 3 种方式,也称为 flavours :

class pathlib. PurePath ( *pathsegments )

表示系统路径风味的一般类 (实例化它会创建 PurePosixPath PureWindowsPath ):

>>> PurePath('setup.py')      # Running on a Unix machine
PurePosixPath('setup.py')
						

每元素的 pathsegments can be either a string representing a path segment, or another path object:

>>> PurePath('foo', 'some/path', 'bar')
PurePosixPath('foo/some/path/bar')
>>> PurePath(Path('foo'), Path('bar'))
PurePosixPath('foo/bar')
						

pathsegments 为空,则假定当前目录:

>>> PurePath()
PurePosixPath('.')
						

当给出几个绝对路径时,采用最后路径作为锚 (模仿 os.path.join() ‘s behaviour):

>>> 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 ,此路径风味表示非 Windows 文件系统路径:

>>> PurePosixPath('/etc')
PurePosixPath('/etc')
						

pathsegments 的指定类似于 PurePath .

class pathlib. PureWindowsPath ( *pathsegments )

子类化的 PurePath ,此路径风味表示 Windows 文件系统路径:

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

pathsegments 的指定类似于 PurePath .

不管在哪个系统中运行,可以实例化所有这些类,因为它们不提供任何做系统调用的操作。

11.1.2.1. 一般特性

路径不可变且可哈希。相同风味的路径可比较且可排序。这些特性遵守风味的大小写折叠语义:

>>> 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. 运算符

斜杠运算符帮助创建子级路径,类似于 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'
					

注意

调用 bytes 仅推荐在 Unix。在 Windows,Unicode 形式是文件系统路径的典型表示。

11.1.2.3. 访问单个部分

要访问路径的各个部分 (组件),使用以下特性:

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

A string representing the drive letter or name, if any:

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

UNC shares are also considered drives:

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

A string representing the (local or global) root, if any:

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

UNC shares always have a root:

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

The concatenation of the drive and root:

>>> 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:/')
						
PurePath. parent

路径的逻辑父级:

>>> p = PurePosixPath('/a/b/c/d')
>>> p.parent
PurePosixPath('/a/b/c')
						

You cannot go past an anchor, or empty path:

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

注意

This is a purely lexical operation, hence the following behaviour:

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

If you want to walk an arbitrary filesystem path upwards, it is recommended to first call Path.resolve() so as to resolve symlinks and eliminate ”..” components.

PurePath. 名称

A string representing the final path component, excluding the drive and root, if any:

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

UNC drive names are not considered:

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

The file extension of the final component, if any:

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

A list of the path’s file extensions:

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

The final path component, without its suffix:

>>> PurePosixPath('my/library.tar.gz').stem
'library.tar'
>>> PurePosixPath('my/library.tar').stem
'library'
>>> PurePosixPath('my/library').stem
'library'
						
PurePath. as_posix ( )

Return a string representation of the path with forward slashes ( / ):

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

Return whether the path is absolute or not. A path is considered absolute if it has both a root and (if the flavour allows) a drive:

>>> 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 if the path is considered reserved under Windows, False otherwise. With PurePosixPath , False is always returned.

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

File system calls on reserved paths can fail mysteriously or have unintended effects.

PurePath. joinpath ( *other )

Calling this method is equivalent to combining the path with each of the other arguments in turn:

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

Match this path against the provided glob-style pattern. Return True if matching is successful, False 否则。

pattern is relative, the path can be either relative or absolute, and matching is done from the right:

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

pattern is absolute, the path must be absolute, and the whole path must match:

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

As with other methods, case-sensitivity is observed:

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

Compute a version of this path relative to the path represented by other . If it’s impossible, ValueError is raised:

>>> 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 changed. If the original path doesn’t have a name, ValueError is raised:

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

返回的新路径带 suffix changed. If the original path doesn’t have a suffix, the new suffix is appended instead:

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

11.1.3. 具体路径

具体路径是纯路径类的子类。除后者提供的操作外,它们还提供对路径对象做系统调用的方法。实例化具体路径有 3 种方式:

class pathlib. 路径 ( *pathsegments )

子类化的 PurePath ,此类表示系统路径风味的具体路径 (实例化它创建 PosixPath WindowsPath ):

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

pathsegments 的指定类似于 PurePath .

class pathlib. PosixPath ( *pathsegments )

子类化的 Path and PurePosixPath ,此类表示非 Windows 文件系统具体路径:

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

pathsegments 的指定类似于 PurePath .

class pathlib. WindowsPath ( *pathsegments )

子类化的 Path and PureWindowsPath ,此类表示 Windows 文件系统具体路径:

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

pathsegments 的指定类似于 PurePath .

只可以实例化对应系统风味的类 (允许系统调用不兼容风味路径,会导致应用程序 Bug 或故障):

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

Concrete paths provide the following methods in addition to pure paths methods. Many of these methods can raise an OSError if a system call fails (for example because the path doesn’t exist):

classmethod Path. cwd ( )

返回表示当前目录的新路径对象 (如返回通过 os.getcwd() ):

>>> Path.cwd()
PosixPath('/home/antoine/pathlib')
							
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() returns whether the symlink points to an existing file or directory.

Path. glob ( pattern )

Glob the given pattern in the directory represented by this path, yielding all matching files (of any kind):

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

The “ ** ” pattern means “this directory and all subdirectories, recursively”. In other words, it enables recursive 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. group ( )

Return the name of the group owning the file. KeyError is raised if the file’s gid isn’t found in the system database.

Path. is_dir ( )

返回 True if the path points to a directory (or a symbolic link pointing to a directory), False if it points to another kind of file.

False is also returned if the path doesn’t exist or is a broken symlink; other errors (such as permission errors) are propagated.

Path. is_file ( )

返回 True if the path points to a regular file (or a symbolic link pointing to a regular file), False if it points to another kind of file.

False is also returned if the path doesn’t exist or is a broken symlink; other errors (such as permission errors) are propagated.

返回 True if the path points to a symbolic link, False 否则。

False is also returned if the path doesn’t exist; other errors (such as permission errors) are propagated.

Path. is_socket ( )

返回 True if the path points to a Unix socket (or a symbolic link pointing to a Unix socket), False if it points to another kind of file.

False is also returned if the path doesn’t exist or is a broken symlink; other errors (such as permission errors) are propagated.

Path. is_fifo ( )

返回 True if the path points to a FIFO (or a symbolic link pointing to a FIFO), False if it points to another kind of file.

False is also returned if the path doesn’t exist or is a broken symlink; other errors (such as permission errors) are propagated.

Path. is_block_device ( )

返回 True if the path points to a block device (or a symbolic link pointing to a block device), False if it points to another kind of file.

False is also returned if the path doesn’t exist or is a broken symlink; other errors (such as permission errors) are propagated.

Path. is_char_device ( )

返回 True if the path points to a character device (or a symbolic link pointing to a character device), False if it points to another kind of file.

False is also returned if the path doesn’t exist or is a broken symlink; other errors (such as permission errors) are propagated.

Path. iterdir ( )

When the path points to a directory, yield path objects of the directory contents:

>>> 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() but, if the path points to a symbolic link, the symbolic link’s mode is changed rather than its target’s.

Path. lstat ( )

Path.stat() but, if the path points to a symbolic link, return the symbolic link’s information rather than its target’s.

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

Create a new directory at this given path. If mode is given, it is combined with the process’ umask value to determine the file mode and access flags. If the path already exists, FileExistsError 被引发。

parents is true, any missing parents of this path are created as needed; they are created with the default permissions without taking mode into account (mimicking the POSIX mkdir -p 命令)。

parents is false (the default), a missing parent raises FileNotFoundError .

Path. open ( mode='r' , buffering=-1 , encoding=None , errors=None , newline=None )

Open the file pointed to by the path, like the built-in open() function does:

>>> p = Path('setup.py')
>>> with p.open() as f:
...     f.readline()
...
'#!/usr/bin/env python3\n'
							
Path. owner ( )

Return the name of the user owning the file. KeyError is raised if the file’s uid isn’t found in the system database.

Path. rename ( target )

Rename this file or directory to the given target . 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)
>>> target.open().read()
'some text'
							
Path. replace ( target )

Rename this file or directory to the given target 。若 target points to an existing file or directory, it will be unconditionally replaced.

Path. resolve ( )

Make the path absolute, resolving any symlinks. A new path object is returned:

>>> p = Path()
>>> p
PosixPath('.')
>>> p.resolve()
PosixPath('/home/antoine/pathlib')
							

”..” components are also eliminated (this is the only method to do so):

>>> p = Path('docs/../setup.py')
>>> p.resolve()
PosixPath('/home/antoine/pathlib/setup.py')
							

If the path doesn’t exist, FileNotFoundError is raised. If an infinite loop is encountered along the resolution path, RuntimeError 被引发。

Path. rglob ( pattern )

这就像调用 glob() with “ ** ” added in front of the given pattern :

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

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

使此路径符号链接到 target 。在 Windows, target_is_directory 必须是 True (默认 False ) if the link’s target is a directory. Under POSIX, target_is_directory ‘s value is ignored.

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

注意

The order of arguments (link, target) is the reverse of os.symlink() ‘s.

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

在此给定路径创建文件。若 mode is given, it is combined with the process’ umask value to determine the file mode and access flags. If the file already exists, the function succeeds if exist_ok is true (and its modification time is updated to the current time), otherwise FileExistsError 被引发。

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