一、pathlib
库概述
- 功能:以面向对象方式处理文件系统路径,替代传统的
os.path
字符串拼接。 - 核心类:
Path
:具体路径对象(支持实际文件操作)PurePath
:纯路径计算对象(不涉及实际IO操作)
- 优势:
- 链式方法调用,代码更简洁
- 自动处理跨平台路径差异(
/
vs\
) - 支持路径解析与组合
- 导入方式:
from pathlib import Path
二、核心操作详解
1. 创建路径对象
操作类型 | 示例代码 | 说明 |
---|---|---|
当前目录 | p = Path() | 等价于 Path.cwd() |
绝对路径 | p = Path("/usr/bin/python") | 直接指定完整路径 |
相对路径 | p = Path("docs/report.pdf") | 基于当前工作目录解析 |
用户目录 | p = Path.home() / "Downloads" | 使用 / 运算符拼接路径 |
2. 路径解析与组合
方法/属性 | 示例代码 | 输出示例 |
---|---|---|
path.name | Path("dir/file.txt").name | file.txt |
path.stem | Path("file.tar.gz").stem | file.tar |
path.suffix | Path("file.tar.gz").suffix | .gz |
path.parent | Path("a/b/c.txt").parent | a/b (Path对象) |
path.parts | Path("/a/b/c.txt").parts | ('/', 'a', 'b', 'c.txt') |
/ 运算符 | Path("a") / "b" / "c.txt" | a/b/c.txt |
path.joinpath() | Path("a").joinpath("b", "c") | a/b/c |
3. 路径检测与属性
方法 | 示例代码 | 说明 |
---|---|---|
path.exists() | Path("file.txt").exists() | 路径是否存在 |
path.is_file() | Path("file.txt").is_file() | 是否为文件 |
path.is_dir() | Path("docs").is_dir() | 是否为目录 |
path.is_absolute() | Path("a/b").is_absolute() | 是否为绝对路径 |
path.stat() | Path("file.txt").stat().st_size | 获取文件大小(字节) |
path.resolve() | Path("../a").resolve() | 解析符号链接并返回绝对路径 |
4. 文件操作
方法 | 示例代码 | 说明 |
---|---|---|
path.touch() | Path("new.txt").touch() | 创建空文件(类似 touch ) |
path.mkdir() | Path("new_dir").mkdir() | 创建目录(可设置 parents=True 递归创建) |
path.rename() | p.rename("new_name.txt") | 重命名/移动文件 |
path.unlink() | Path("temp.txt").unlink() | 删除文件 |
path.rmdir() | Path("empty_dir").rmdir() | 删除空目录 |
5. 文件读写
方法 | 示例代码 | 说明 |
---|---|---|
path.read_text() | Path("file.txt").read_text() | 读取文本(自动解码) |
path.write_text() | Path("file.txt").write_text("Hello") | 写入文本(覆盖) |
path.read_bytes() | Path("img.png").read_bytes() | 读取二进制数据 |
path.write_bytes() | Path("data.bin").write_bytes(b"\x00") | 写入二进制数据 |
6. 目录遍历
方法 | 示例代码 | 说明 |
---|---|---|
path.iterdir() | [p for p in Path().iterdir()] | 遍历目录条目(非递归) |
path.glob() | Path().glob("**/*.py") | 通配符搜索(支持 ** 递归) |
path.rglob() | Path().rglob("*.log") | 递归通配符搜索(等价于 glob("**/*.log") ) |
三、实际应用示例
1. 批量重命名图片
folder = Path("photos")
for idx, img_path in enumerate(folder.glob("*.jpg")):
new_name = f"vacation_{idx:03d}.jpg"
img_path.rename(folder / new_name)
2. 统计目录大小
def get_dir_size(path):
return sum(f.stat().st_size for f in path.rglob("*") if f.is_file())
size = get_dir_size(Path("/data"))
print(f"总大小: {size / 1024**2:.2f} MB")
3. 配置文件读取
config_path = Path.home() / ".config/app.conf"
if config_path.exists():
settings = {
line.split("=")[0]: line.split("=")[1].strip()
for line in config_path.read_text().splitlines()
}
else:
settings = {}
4. 创建项目结构
project = Path("my_project")
(project / "src/utils").mkdir(parents=True, exist_ok=True)
(project / "docs/api.md").touch()
(project / "README.md").write_text("# My Project\n")
四、与传统 os.path
对比
操作 | os.path 写法 | pathlib 写法 |
---|---|---|
路径拼接 | os.path.join("a", "b") | Path("a") / "b" |
获取父目录 | os.path.dirname("/a/b/c") | Path("/a/b/c").parent |
获取文件名 | os.path.basename("/a/b/c.txt") | Path("/a/b/c.txt").name |
检测文件存在 | os.path.exists("file.txt") | Path("file.txt").exists() |
递归创建目录 | os.makedirs("a/b", exist_ok=True) | Path("a/b").mkdir(parents=True, exist_ok=True) |
五、注意事项
1. 路径标准化
- 统一斜杠方向:
Path
对象在字符串转换时自动适配当前系统str(Path("a/b/c")) # Windows 输出 'a\\b\\c',Linux/macOS 输出 'a/b/c'
2. 性能优化
- 大量文件操作:
glob()
和rglob()
可能较慢,考虑使用os.scandir()
处理海量文件
3. 异常处理
- 操作失败处理:
try: Path("important.txt").unlink() except FileNotFoundError: print("文件不存在") except PermissionError: print("无删除权限")
4. 兼容性
- 旧版 Python:Python < 3.6 的
pathlib
功能受限(如缺失os.fspath()
支持)
六、最佳实践
- 优先使用
/
运算符:路径拼接更直观 - 链式调用:
(Path.cwd() / "data") .mkdir(exist_ok=True) .joinpath("2023.log") .touch()
- 利用解析功能:
path = Path("docs/reports/final.pdf") print(f"目录: {path.parent}, 文件名: {path.stem}, 扩展名: {path.suffix}")