Python内置库:pathlib(文件路径操作)
官方文档: pathlib — Object-oriented filesystem paths
一、基础使用
- 遍历子目录
- 使用通配符遍历文件
- 拼接路径
- 获取标准化后的绝对路径
- 查询路径常规属性
- 打开文件
from pathlib import Path
print('1.1 查询指定目录的子目录')
p = Path('D:/Envs')
print([sub_p for sub_p in p.iterdir() if sub_p.is_dir()])
print('1.2 使用通配符查询目录中的某类文件')
p = Path('D:/Envs/flask_env/Scripts')
# glob的结果是一个生成器,需要使用list进行转换
print(list(p.glob('*.bat')))
print('1.3 拼接路径,以下三种方式都可以')
p = Path('D:/Envs')
p = p / 'flask_env'
print(p)
p = p.joinpath('Scripts')
print(p)
p = p.joinpath(Path('activate.bat'))
print(p)
print('1.4 获取绝对路径,会自动消除符号链接使之称为一个标准化的路径表示,Windows中,斜杠会被转换为反斜杠')
p = Path('.')
print(p.resolve())
print('1.5 查询路径常规属性')
p = Path('D:/Envs')
print(p.exists())
print(p.is_dir())
print(p.is_file())
print('1.6 打开文件,以下两种方式都可以')
p = Path('./test.txt')
with open(p) as f:
print(f.read())
with p.open() as f:
print(f.read())
1.1 查询指定目录的子目录
[WindowsPath('D:/Envs/django_env'), WindowsPath('D:/Envs/flask_env'), WindowsPath('D:/Envs/study')]
1.2 使用通配符查询目录中的某类文件
[WindowsPath('D:/Envs/flask_env/Scripts/activate.bat'), WindowsPath('D:/Envs/flask_env/Scripts/deactivate.bat')]
1.3 拼接路径,以下三种方式都可以
D:\Envs\flask_env
D:\Envs\flask_env\Scripts
D:\Envs\flask_env\Scripts\activate.bat
1.4 获取绝对路径,会自动消除符号链接使之成为一个标准化的路径表示,Windows中,斜杠会被转换为反斜杠
D:\Projects\pathlib_test
1.5 查询路径常规属性
True
True
False
1.6 打开文件,以下两种方式都可以
This is a test file
This is a test file
二、Pure paths
Pure paths在不对文件系统进行实际操作的前提下,提供了各种操作路径的方法。该模块提供了三个类PurePath、PureWindowsPath、PurePosixPath,从名称可以看出PureWindowsPath用于Windows系统,PurePosixPath用于非Windows系统,当然也可以直接使用基类PurePath,从类定义上看,PureWindowsPath和PurePosixPath只是在 _flavour
上提前定义好了操作系统类型,直接使用PurePath会根据 os.name
自动识别当前操作系统。
注: 本章节示例来自官方文档pathlib — Object-oriented filesystem paths
2.1 初始化
初始化时可以传入一个或多个参数,参数可以是路径字符串,也可以是 pathlib.Path
对象,若没有传入任何参数,则默认为当前目录。
>>> PurePath('setup.py') # Running on a Unix machine
PurePosixPath('setup.py')
>>> PurePath('foo', 'some/path', 'bar')
PurePosixPath('foo/some/path/bar')
>>> PurePath(Path('foo'), Path('bar'))
PurePosixPath('foo/bar')
>>> PurePath()
PurePosixPath('.')
路径中间的 //
和 .
会被自动优化。
>>> PurePath('foo//bar')
PurePosixPath('foo/bar')
>>> PurePath('//foo/bar')
PurePosixPath('//foo/bar')
>>> PurePath('foo/./bar')
PurePosixPath('foo/bar')
>>> PurePath('foo/../bar')
PurePosixPath('foo/../bar')
2.2 通用属性
一个 PurePath
或 其子类,都可以直接用在任何实现了 os.PathLike 接口的地方,并且如果想要 PurePath
对象代表的路径的字符串值,直接使用str即可。
>>> import os
>>> p = PurePath('/etc')
>>> os.fspath(p)
'/etc'
>>> p = PurePath('/etc')
>>> str(p)
'/etc'
>>> bytes(p)
b'/etc'
>>> p = PureWindowsPath('c:/Program Files')
>>> str(p)
'c:\\Program Files'
parts
属性提供了根据路径分隔符分隔的元组。
>>> p = PurePath('/usr/bin/python3')
>>> p.parts
('/', 'usr', 'bin', 'python3')
>>> p = PureWindowsPath('c:/Program Files/PSF')
>>> p.parts
('c:\\', 'Program Files', 'PSF')
2.3 其他方法和属性
PurePath.drive
获取路径中的盘符(如果有),否则返回空字符串。
PurePath.anchor
PurePath.drive
和 PurePath.root
的结合。
>>> PureWindowsPath('c:/Program Files/').anchor
'c:\\'
>>> PureWindowsPath('c:Program Files/').anchor
'c:'
>>> PurePosixPath('/etc').anchor
'/'
>>> PureWindowsPath('//host/share').anchor # UNC shares
'\\\\host\\share\\'
PurePath.parents
返回一个存储了各个祖先节点的不可变序列。在 Python 3.10 开始,支持对其切片以及使用负向索引。
>>> 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('foo/..') # 如果想要实际的路径信息,可以使用Path对象,先调用Path.resolve()获取绝对路径
>>> p.parent
PurePosixPath('foo')
PurePath.name
按路径分割后,返回最后一级名称(会自动去除盘符 drive
和根路径符 root
)。
PurePosixPath('my/library/setup.py').name
'setup.py'
PurePath.suffix
返回路径中的文件名后缀(如果有),如 .py
。
PurePath.suffixes
返回路径中最后一级的文件名后缀列表(如果有),如“library.tar.gz”的suffixes值为 ['.tar', '.gz']
。
PurePath.stem
返回路径中最后一级的文件名(不含后缀 PurePath.suffix
),如“library.tar.gz”的stem值为 library.tar
。
PurePath.as_posix()
返回以斜杠表示的路径。
PurePath.is_absolute()
是否为绝对路径。
PurePath.joinpath(*pathsegments)
拼接路径,可以传入一个或多个字符串或Path对象。
PurePath.match(pattern, *, case_sensitive=None)
判断路径是否符合指定通配符模式。 case_sensitive
参数( Python 3.12 增加)在Windows系统默认为False,其他系统默认为True。如果 pattern
也是PurePath对象,此方法匹配效率会更高。
>>> 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('*.py')
>>> PurePath('a/b.py').match(pattern)
True
PurePath.with_name(name)
使用指定的name替换原有的name,如果原路径就没有name,则抛出异常。
>>> 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替换原有的stem,如果原路径就没有stem,则抛出异常。
>>> 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
PurePath.with_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')
三、path实体
path实体也提供了三个类Path(基类)、PosixPath、WindowsPath,Path继承自PurePath,所以PurePath支持的操作,path实体的三个类也是支持的。path实体与pure path区别在于,path实体对象支持系统操作,如获取绝对路径、遍历目录的所有子目录和文件、打开文件等,所以需要特别注意,在使用Path类时,可能会因为系统不支持导致抛出OSError等异常。
注: 本章节部分示例来自官方文档pathlib — Object-oriented filesystem paths
3.1 常用方法
Path.cwd()
返回当前路径,同 os.getcwd()
。
Path.home()
返回当前用户的home目录,同 os.path.expanduser()
。
Path.stat(*, follow_symlinks=True)
获取路径详细信息,同 os.stat()
。 follow_symlinks
参数在 Python 3.10 开始添加。
>>> p = Path('setup.py')
>>> p.stat().st_size
956
>>> p.stat().st_mtime
1327883547.852554
Path.chmod(mode, *, follow_symlinks=True)
修改文件权限,同 os.chmod()
。 follow_symlinks
参数在 Python 3.10 添加。
>>> p = Path('setup.py')
>>> p.stat().st_mode
33277
>>> p.chmod(0o444)
>>> p.stat().st_mode
33060
Path.exists(*, follow_symlinks=True)
检查路径是否存在。 follow_symlinks
参数在 Python 3.12 添加。
Path.expanduser()
返回填充了home目录的路径。该方法在 Python 3.5 添加。
>>> p = PosixPath('~/films/Monty Python')
>>> p.expanduser()
PosixPath('/home/eric/films/Monty Python')
Path.glob(pattern, *, case_sensitive=None)
使用通配符遍历当前路径下的所有目录和文件。 case_sensitive
( Python 3.12 添加)默认为None,即使用当前系统的大小写规则,也可手动指定。当 pattern
以路径分隔符结尾,则只会列出目录,不会列出文件(该特性在 Python 3.11 添加)。
>>> 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')]
Path.group()
返回路径的属组。
Path.is_dir()
检查路径是否是目录。
Path.is_file()
检查路径是否是文件。
Path.is_junction()
检查路径是否是junction快捷方式(Windows系统专用)。
Path.is_mount()
判断路径是否是一个挂载点(该方法在 Python 3.7 添加,在 Python 3.12 支持Windows系统)。
Path.is_symlink()
判断路径是否是符号链接,如果路径不存在也会返回False。
Path.is_socket()
检查路径是否指向Unix socket文件,如果路径不存在也会返回False。
Path.is_fifo()
检查路径是否指向FIFO存储,如果路径不存在也会返回False。
Path.is_block_device()
检查路径是否指向块设备,如果路径不存在也会返回False。
Path.is_char_device()
检查路径是否指字符设备,如果路径不存在也会返回False。
Path.iterdir()
以生成器的方式遍历路径下的所有目录和文件。
Path.walk(top_down=True, on_error=None, follow_symlinks=False)
该方法在 Python 3.12 添加。递归遍历指定路径下的所有目录和文件,使用时由生成器每次生成一个三元组(当前遍历目录,子目录名列表,子文件名列表),想要使用某个子目录或子文件时,其全路径为“当前遍历目录+目录名/文件名”。
top_down
默认为True,即从上到下遍历,为False时表示从下到上遍历,“上下”的区别就是从当前目录的子目录开始往最里一层一层遍历遍历,还是从最深的子目录往外一层一层遍历。on_error
默认为None,即忽略walk过程中的异常,也可手动指定一个可调用对象来处理异常,该对象的要求是接受发生的异常(OSError对象)。follow_symlinks
默认为False,即在walk时,不会自动跟踪链接到真实的路径,列出的结果就是链接本身(该操作区别于os.walk()
)。
示例:有路径结构如下
test1
- test2
- test2.txt
- test1.txt
>>> import pathlib
>>> p = pathlib.Path('Z:\\Projects\\Daily Test\\pathlib_test\\test1')
>>> for root, dirnames, filenames in p.walk():
print(root)
print(dirnames)
print(filenames)
Z:\Projects\Daily Test\pathlib_test\test1
['test2']
['test1.txt']
Z:\Projects\Daily Test\pathlib_test\test1\test2
[]
['test2.txt']
>>>
>>> for root, dirnames, filenames in p.walk(top_down=False):
print(root)
print(dirnames)
print(filenames)
Z:\Projects\Daily Test\pathlib_test\test1\test2
[]
['test2.txt']
Z:\Projects\Daily Test\pathlib_test\test1
['test2']
['test1.txt']
Path.lchmod(mode)
类似 Path.chmod()
,修改文件权限,区别在于,如果路径是一个链接,则只会修改链接本身,而链接指向的对象不会被修改。
Path.lstat()
类似 Path.stat()
,修改文件属性,区别在于,如果路径是一个链接,则只会修改链接本身,而链接指向的对象不会被修改。
Path.mkdir(mode=0o777, parents=False, exist_ok=False)
创建目录。 parents
默认False,表示路径中的某个父目录不存在则会抛错, exist_ok
默认为False(该参数在 Python 3.5 添加),表示创建的路径已经存在则会抛错,这两个参数的行为与POSIX系统中的 mkdir -p
命令执行一致。
Path.open(mode='r', buffering=-1, encoding=None, errors=None, newline=None)
打开文件,同内置的open函数。
Path.owner()
返回路径的属主。
Path.read_bytes()
以byte类型返回文件的二进制内容。(该方法在 Python 3.5 添加)
Path.read_text(encoding=None, errors=None)
返回解码后的文件文本内容。文件打开后会立即关闭,参数的行为与内置的open函数相同。(该方法在 Python 3.5 添加)
Path.readlink()
返回链接指向的真实文件的路径,同 os.readlink()
。(该方法在 Python 3.9 添加)
Path.rename(target)
重命名文件或目录,并返回新的路径对象(返回值在 Python 3.8 添加)。在Unix是上静默修改,在Windows上则会修改失败。同 os.rename()
。
Path.replace(target)
替换一个已有的文件或目录,并返回新的路径对象(返回值在 Python 3.8 添加),如果待替换的路径为已存在的文件或空目录,则会强制替换。
Path.absolute()
返回绝对路径,但不会自动标准化路径,也不会自动解析符号链接。
Path.resolve(strict=False)
返回Path对象的绝对路径,会自动消除符号链接、“.”、“..”等格式的路径。当 strict=True
且文件路径不存在时,则抛出异常。(该参数在 Python 3.6 添加,在这之前版本默认为True)
>>> p = Path()
>>> p
PosixPath('.')
>>> p.resolve()
PosixPath('/home/antoine/pathlib')
>>> p = Path('docs/../setup.py')
>>> p.resolve()
PosixPath('/home/antoine/pathlib/setup.py')
Path.rglob(pattern, *, case_sensitive=None)
按照给定通配符模式递归遍历子目录及文件。 pattern
参数若以路径分隔符结尾,则只遍历所有子目录,不会遍历文件(该规则在 Python 3.11 添加)。 case_sensitive
默认为None,即跟随系统大小写规则。(该参数在 Python 3.12 添加)。
Path.rmdir()
移除指定空目录(非空目录无法移除)。
Path.samefile(other_path)
判断两个文件是否相等, other_path
可以是Path对象,也可以是字符串。(该方法在 Python 3.5 添加)
Path.symlink_to(target, target_is_directory=False)
使当前Path对象成为一个符号链接,并指向 target
所表示的文件。 target_is_directory
参数在非Windows系统上会被忽略,不生效。
Path.hardlink_to(target)
使当前Path对象成为一个硬链接,并指向 target
所表示的文件。
Path.touch(mode=0o666, exist_ok=True)
创建一个路径,如果 exist_ok=False
且路径已经存在,则会抛出异常。
Path.unlink(missing_ok=False)
移除文件或符号链接。如果此Path对象指向的是目录,请使用 Path.rmdir()
。 missing_ok
默认为False,即路径不存在时抛出异常,反之则忽略异常。(该参数在 Python 3.8 添加)
Path.write_bytes(data)
以字节模式打开文件并写入字节数据,写入完成自动关闭文件。
Path.write_text(data, encoding=None, errors=None, newline=None)
以文本模式打开文件并写入文本数据,同内置的open函数。(该方法在 Python 3.5 添加, newline
参数在 Python 3.10 添加)