前言
pathlib
是 Python 3.4 引入的一个库,用于处理文件路径。它提供了一种简洁、面向对象的方式来操作文件和目录路径,相比于传统的 os
模块,pathlib
更加易于使用和理解,也是官方推荐的使用方法。
Pathlib
库的主要特点包括:
- 面向对象:
Pathlib
路径对象表示文件或目录路径,并提供了一系列方法来操作这些路径。
- 跨平台:
Pathlib
库是跨平台的,可以在不同的操作系统上工作。
- 简洁性:相比传统的
os.path
模块,Pathlib
提供了更简洁和直观的路径操作。
- 功能丰富:
Pathlib
提供了许多用于路径操作的方法,如 joinpath()
, split()
, dirname()
, basename()
等。
对于第一次使用此模块,我们只需要导入一个Path即可。
pathlib库的类介绍
pathlib
模块中包含了两个主要类:Path
和PurePath
。
Path
:表示路径的主要类,用于创建、操作和表示文件系统路径。它有一些常用的属性和方法,如 name
(获取路径的基本名称)、parent
(获取路径的父目录)、exists()
(检查路径是否存在)、is_file()
(检查路径是否为文件)、is_dir()
(检查路径是否为目录)等。
PosixPath
和 WindowsPath
:Path
的子类,分别用于处理 POSIX 和 Windows 系统的路径。它们继承了 Path
的属性和方法,并提供了一些特定于不同操作系统的功能。
PurePath
:Path
的基类,用于处理纯路径,不直接与文件系统交互。它提供了基本的路径操作,但不会涉及实际的文件系统访问。
PurePosixPath
和 PureWindowsPath
:PurePath
的子类,分别表示纯 POSIX 和 Windows 系统的路径。它们用于处理纯路径,不涉及实际文件系统操作。
导入模块
from pathlib import Path
路径操作方法
Path类方法
常用路径属性
pathlib
的属性通过查看源码发现是在Path
的父类 PurePath
中通过装饰器@property
来让方法可以像属性一样被访问。
Path.name
: 用于获取路径中的文件名部分。
Path.stem
: 用于获取路径中的文件名部分但不包括文件扩展名。
Path.suffix
: 用于获取路径中的文件扩展名部分。
Path.suffixes
: 用于获取路径中的文件扩展名部分,但与 Path.suffix
不同的是,Path.suffixes
返回的是一个列表,包含路径中所有的文件扩展名部分,每个扩展名都包括点号 .
。
Path.root
: 用于返回路径的根部分。对于绝对路径来说,根部分就是路径的根目录 \
。
Path.parts
: 用于返回路径的各个部分组成的元组。每个部分都是路径中的一个目录或文件名。
Path.anchor
: 用于返回路径的根目录部分。对于绝对路径,根目录部分就是路径的根目录,在Windowns
中为E:\
,在类Unix
中为\
。
Path.parent
: 用于返回路径的父目录部分。
Path.parents
: 用于返回路径的所有父目录部分,以一个可迭代的对象的形式返回。这个可迭代对象包含了路径的所有父目录,直到根目录为止。
常用路径方法
实例方法返回的类型是:<class 'pathlib.WindowsPath'>
,是一种类路径类型(PathLike),它们实现了文件系统路径的常用操作,如拼接(使用 /
运算符)、解析和修改。这使得处理路径变得更加直观和易于理解。
Path.stat(*)
- 返回一个
os.stat_result
对象,其中包含有关此路径的信息,包括文件的元数据(如大小、权限、最后访问时间等)。
- 此方法与
os.stat()
类似。
file_path = Path('demo.py')
stat_info = file_path.stat()
>>> stat_info
os.stat_result(st_mode=33206, st_ino=74590868828380952, st_dev=3237859167, st_nlink=1, st_uid=0, st_gid=0, st_size=149, st_atime=1709787460, st_mtime=1709787460, st_ctime=1709787445)
>>> stat_info.st_size
149
Path.exists(*)
- 该方法用于检查指定路径是否存在。如果路径存在,则返回
True
;如果路径不存在,则返回 False
。
# 创建一个 Path 对象
file_path = Path("demo.py")
# 检查路径是否存在
if file_path.exists():
print("File exists.")
else:
print("File does not exist.")
Path.expanduser()
path = Path('~/Desktop/file.txt')
expanded_path = path.expanduser()
>>> expanded_path
'C:\Users\redballoon\Desktop\file.txt'
Path.glob(pattern, *, case_sensitive=None)
folder_path = Path('.')
# 查找当前目录下所有以.py结尾的文件
for file_path in folder_path.glob('*/*.py'):
print(file_path)
备注:在一个较大的目录树中使用 "**
" 模式可能会消耗非常多的时间。
Path.is_dir()
- 用于检查指定路径是否为一个目录(文件夹)。如果路径指向一个目录,则返回
True
;如果路径指向一个文件或者不存在的路径,则返回 False
。
my_path = Path('.').is_dir() # True
my_path = Path('demo.py').is_dir() # False
Path.is_file()
- 用于检查指定路径是否为一个文件。如果路径指向一个文件,则返回
True
;如果路径指向一个目录或者不存在的路径,则返回 False
。
my_path = Path('demo.py').is_file() # True
my_path = Path('.').is_file() # False
Path.iterdir()
- 用于遍历指定目录下的所有文件和子目录。具体来说,
iterdir()
方法返回一个迭代器(生成器),通过该迭代器(生成器)可以依次访问目录中的每个子目录项(包括文件和子目录)。
- 子条目会以任意顺序生成,并且不包括特殊条目
'.'
和 '..'
。
# 指定要遍历的目录路径
directory_path = Path(".")
for item in directory_path.iterdir():
if item.is_file(): # 判断是否为文件
print(f"File: {item.name}")
elif item.is_dir(): # 判断是否为目录
print(f"Directory: {item.name}")
Path.walk(top_down=True)
- 用于递归遍历指定目录下的所有文件和子目录。该方法返回一个迭代器,可以按照指定的顺序(从顶层到底层或从底层到顶层)遍历目录结构。
top_down=True
表示按照自顶向下的顺序进行遍历,默认为 True
。如果设置为 False
,则表示按照自底向上的顺序进行遍历。
在 python 3.12 版本加入.暂不讨论
Path.mkdir(parents=False, exist_ok=False)
- 用于创建一个目录。
parents
:如果设置为 True
,则会自动创建必要的父目录;如果设置为 False
,则只创建最后一级目录,默认为 False
。
exist_ok
:如果设置为 True
,当目录已经存在时不会引发异常;如果设置为 False
,当目录已经存在时会引发 FileExistsError
,默认为 False
。
# 创建一个名为 "new_dir" 的目录,如果目录已经存在则不引发异常
Path("new_dir").mkdir(exist_ok=True)
Path.rename(target)
- 用于将当前路径指定的文件或目录重命名为目标路径。这个方法接受一个参数
target
,表示重命名后的目标路径。在 Windows 上,如果 target 存在,则将会引发 FileExistsError
。
# 创建一个名为 "old_name.txt" 的文件
Path("old_name.txt").touch()
# 将文件名从 "old_name.txt" 改为 "new_name.txt"
Path("new_name.txt").rename("new_name.txt")
在windowns中使用确保目标路径(target)不存在:
# 创建一个名为 "old_name.txt" 的文件
Path("old_name.txt").touch()
# 确保目标路径 "new_name.txt" 不存在,然后重命名文件
if not Path("new_name.txt").exists():
Path("old_name.txt").rename("new_name.txt")
else:
# 如果目标路径已经存在,先删除目标路径再重命名
Path("new_name.txt").unlink()
Path("old_name.txt").rename("new_name.txt")
Path.replace(target)
- 用于将当前路径对象替换为目标路径对象。它返回一个新的Path对象,表示替换后的路径。
- Path.replace(target)方法会将当前路径对象指向的文件或目录替换为目标路径对象指向的文件或目录。如果目标路径对象已经存在,则会被替换;如果目标路径对象不存在,则会创建一个新的文件或目录。
- Path.rename(target)与Path.replace(target)的区别:
p.rename(target)
方法是直接在当前路径对象上进行重命名操作,而 Path.replace(target)
方法是创建一个新的 Path
对象来替换目标路径。
# 创建一个名为 "source.txt" 的文件和一个名为 "target.txt" 的文件
Path("source.txt").touch()
Path("target.txt").touch()
# 创建 Path 对象
source_path = Path("source.txt")
target_path = Path("target.txt")
# 将 source.txt 替换为 target.txt
replaced_path = source_path.replace(target_path)
# 打印被替换的文件路径
print(f"被替换的文件路径: {replaced_path}")
print(f"source.txt 是否存在: {source_path.exists()}")
print(f"target.txt 是否存在: {target_path.exists()}")
Path.absolute()
# 创建一个相对路径对象
relative_path = Path("my_folder/my_file.txt")
# 获取相对路径对象的绝对路径
absolute_path = relative_path.absolute()
>>> absolute_path
'E:\pythonProjects\pythonProject\my_folder\my_file.txt'
Path.resolve(strict=False)
- 于获取指定路径对象的绝对路径,并解析可能存在的符号链接(软链接)。
absolute()
与resolve()
的区别:
absolute()
方法不会解析符号链接,而 resolve(strict=False)
方法会尝试解析符号链接。如果需要处理符号链接并获取最终的绝对路径,可以使用 resolve(strict=False)
方法;如果只需要获取绝对路径而不关心符号链接,则可以使用 Path.absolute()
方法。
# 创建一个带符号链接的路径对象
symbolic_link_path = Path("my_folder/my_symbolic_link")
# 获取解析后的绝对路径
resolved_path = symbolic_link_path.resolve()
>>> resolved_path
'E:\pythonProjects\pythonProject\my_folder\my_symbolic_link'
Path.rmdir()
- 用于删除指定的空目录。它会删除路径对象所指向的目录,前提是该目录必须为空,否则会引发OSError异常。
directory_to_delete = Path("my_folder") # # 要删除的目录
directory_to_delete.rmdir() # # 删除目录
Path.touch(exist_ok=True)
- 用于创建一个空文件。如果文件已经存在,则不会引发异常,除非设置了exist_ok参数为False,此时会引发FileExistsError异常。
Path("my_file.txt").touch()
Path.unlink(missing_ok=False)
- 用于删除指定的文件或符号链接。
- 如果给定路径是一个文件,它将永久删除该文件;如果给定路径是一个目录,将引发
IsADirectoryError
异常。
- 如果文件不存在且
missing_ok=False
(默认值),将引发 FileNotFoundError
异常;如果文件不存在且 missing_ok=True
,不会引发异常,函数将直接返回。
# 要删除的文件
file_to_delete = Path("my_file.txt")
try:
# 删除文件
file_to_delete.unlink(missing_ok=True)
print(f"文件 {file_to_delete} 删除成功")
except OSError as e:
print(f"删除文件 {file_to_delete} 失败: {e}")
*Path.joinpath(other)**
# 连接相对路径
p1 = Path('dir1/dir2')
p2 = p1.joinpath('file.txt')
print(p2) # 输出: dir1/dir2/file.txt
# 连接多个路径组件
p = Path('folder1', 'folder2', 'demo.txt').joinpath()
print(p) # 输出: folder1\folder2\demo.txt
pathlib对应的os模块的工具
以下是一个映射了 os
与 PurePath``Path
对应相同的函数的表。
备注:以下函数/方法对并不全都是等价的。 在它们之中,有的虽然具有相互重叠的使用场景,但其语义有所不同。 这包括 os.path.abspath()
与 Path.absolute()
, os.path.relpath()
与 PurePath.relative_to()
。