pathlib 是 Python 现代化的文件路径处理模块,它以面向对象的方式操作文件和目录,直观、安全、跨平台。
先看一个小示例,理解 Path 对象的构造、成分解析与常用判断,再看完整速查表和实践技巧。


入门操作和示例

下面这个代码块用于快速理解pathlib的高频基础操作,有助于简表的理解:Path() 构建、成分解析、路径判断、拼接(含 /joinpath 等价说明)、touch()mkdir() 的配合,以及 iterdir()os.walk() 的对比使用法。

from pathlib import Path #Path是pathlib的核心类
import shutil #pathlib结合shutil完成文件移动
import os #用于对比展示

# 1.读取当前目录及文件
Path.cwd() #读取当前目录 
list(Path.cwd().iterdir()) # .iterdir()展示当前目录下文件,返回一个惰性generator

# 2. Path() 构建对象(可以传多个组件)
p = Path('project', 'data', 'raw', 'sample.txt')
p1 = Path('project/data/raw/sample.txt')
p2 = Path('project\data\\raw\sample.txt')
print("构建的 Path:", p)  # project/data/raw/sample.txt
print(p,"\n",p1,"\n",p2) #三者等价,pathlib会自行处理斜杠方向,但是\在python中是转义字符,且\r是回车符,且因此这里用\\r。综上还是建议培养习惯,使用/运算符

# 3. 成分解析(文件名/后缀/父级等)
print("name:", p.name)        # 'sample.txt'
print("stem:", p.stem)        # 'sample'
print("suffix:", p.suffix)    # '.txt'
print("suffixes:", p.suffixes) # 若有多后缀 e.g. '.tar.gz'
print("parent:", p.parent)    # Path('project/data/raw')

# 4. / 操作符 等价于 .joinpath()
a = Path('project') / 'data' / 'raw'
b = Path('project').joinpath('data', 'raw')
assert a == b  # True

# 5. Path.touch()创建文件
#注意:Path.touch()不能创建缺失的父目录
f = Path('project/data/newdir/newfile.txt')
try:
    f.touch()  # 如果 parent 不存在会抛错 FileNotFoundError
except FileNotFoundError:
    print("touch 失败,因为父目录不存在")

# 正确做法:先创建父目录,再 touch
f.parent.mkdir(parents=True, exist_ok=True)
f.touch(exist_ok=True)
print("已创建文件:", f)

# 6. 路径判断与解析
print("exists:", f.exists())
print("is_file:", f.is_file())
print("is_dir (parent):", f.parent.is_dir())
print("resolve:", f.resolve())  # 绝对路径并解析符号链接

要点

  • / 操作符与 .joinpath() 完全等价,风格上更直观,建议在代码中优先使用 /
  • Path.touch() 只会创建文件(或更新时间戳),不会创建不存在的父目录;如果父目录不存在必须先 path.parent.mkdir(parents=True, exist_ok=True)
  • 在与传统 API(接受字符串路径)交互时,使用 str(path)将其转为字符串。

一、核心思路

  • Path 对象即路径:不再需要拼字符串。
  • 链式调用:路径解析、拼接、判断、操作可一气呵成。
  • 跨平台兼容:自动处理 Windows 与 Linux/macOS 路径差异。
  • 与 shutil 协同:完成复制、移动、备份等高级操作。

二、pathlib 高频操作简表

类别 操作 / 属性 关键参数 / 说明 常用参数示例 / 值
路径创建与拼接 Path() 构造路径对象,可拼接多个字符串。 from pathlib import Path``path = Path('folder', 'subfolder', 'file.txt')
/ 操作符 直观的路径拼接符。 等价于 .joinpath() Path('folder') / 'subfolder' / 'file.txt'
.joinpath() 拼接多个路径组件。 path.joinpath('subdir', 'file.txt')
路径成分解析 .name 返回路径的最后部分(文件名+后缀)。 Path('/a/b.txt').name → 'b.txt'
.stem 文件名(无后缀)。 Path('/a/b.txt').stem → 'b'
.suffix 文件后缀。 Path('/a/b.tar.gz').suffix → '.gz'
.suffixes 所有后缀列表。 Path('/a/b.tar.gz').suffixes → ['.tar', '.gz']
.parent 父级目录路径。 Path('/a/b.txt').parent → Path('/a')
.parents 所有上级目录(元组)。 Path('/a/b/c.txt').parents[0] → Path('/a/b')
.with_name() 替换文件名部分。 path.with_name('new_file.txt')
.with_suffix() 替换文件后缀。 path.with_suffix('.png')
路径解析与判断 .resolve() 转为绝对路径并解析符号链接。 path.resolve()
.exists() 判断路径是否存在。 path.exists()
.is_dir() 判断是否为目录。 path.is_dir()
.is_file() 判断是否为文件。 path.is_file()
.stat() 获取文件元信息(大小、修改时间等)。 path.stat().st_size(文件大小)
目录与文件创建 .mkdir() 创建目录。 parents=False(是否创建父级目录)exist_ok=False(目录存在是否报错)示例:Path('data/sub').mkdir(parents=True, exist_ok=True)
.touch() 创建空文件或更新访问时间。 注意:不会自动创建父级目录 mode=0o666, exist_ok=True示例:Path('log.txt').touch(exist_ok=True)
重命名与移动 .rename(target) 重命名或移动文件(目标存在时报错)。 Path('a.txt').rename('b.txt')
.replace(target) 重命名或移动文件(目标存在则覆盖)。 Path('a.txt').replace('b.txt')
文件读写操作 .read_text() 以文本模式读取文件。 encoding='utf-8'``Path('readme.txt').read_text()
.write_text() 以文本模式写入文件。 encoding='utf-8'``Path('out.txt').write_text('Hello!')
.read_bytes() 以二进制模式读取文件。 Path('data.bin').read_bytes()
.write_bytes() 以二进制模式写入文件。 Path('data.bin').write_bytes(b'data')
文件与目录删除 .unlink() 删除文件。 missing_ok=False``Path('old.txt').unlink(missing_ok=True)
.rmdir() 删除空目录。 Path('tmp').rmdir()
目录遍历与匹配 .iterdir() 遍历目录下所有条目。 返回 generator(惰性) for p in Path('folder').iterdir(): print(p)
.glob(pattern) 匹配模式(非递归)。 Path('.').glob('*.py')
.rglob(pattern) 递归匹配模式。 Path('.').rglob('**/*.txt')
文件操作(结合 shutil) shutil.copy(src, dst) 复制文件内容,不含元数据。 import shutil``shutil.copy(Path('source.txt'), Path('copy.txt'))
shutil.copy2(src, dst) 复制文件并保留元数据。 shutil.copy2(Path('source.txt'), Path('backup/source.txt'))
shutil.copytree(src, dst) 递归复制整个目录树。 shutil.copytree(Path('src_dir'), Path('backup_dir'))
shutil.rmtree() 删除文件夹。【慎用】 shutil.rmtree("./subfolder")

三、实用示例与技巧

1️⃣ 创建目录与文件

from pathlib import Path

# 创建目录及父目录
data_dir = Path('data/raw')
data_dir.mkdir(parents=True, exist_ok=True)

# 创建文件(注意:touch 不会创建父目录,因此要先 mkdir)
file_path = data_dir / 'sample.txt'
file_path.touch(exist_ok=True)

2️⃣ 文件复制(与 shutil 搭配)

from pathlib import Path
import shutil

src_path = Path('data/raw/sample.txt')
dst_path = Path('backup/sample_backup.txt')

# 确保目标目录存在
dst_path.parent.mkdir(parents=True, exist_ok=True)

# 复制文件(保留元数据)
shutil.copy2(src_path, dst_path)

3️⃣ 安全重命名与覆盖

from pathlib import Path

src = Path('backup/sample_backup.txt')
dst = Path('backup/sample_final.txt')

# rename:若目标已存在,会报错
# replace:若目标已存在,会覆盖
src.replace(dst)

4️⃣ 遍历目录与模式匹配

from pathlib import Path

for txt_file in Path('data').rglob('*.txt'):
    print(txt_file.name)

5️⃣ 文件存在性与删除

file = Path('temp.txt')
if file.exists():
    file.unlink()  # 删除文件

6️⃣rglob递归遍历

场景 一行式代码
递归拿到所有文件(含子目录) file_list = [p for p in Path(src).rglob('*') if p.is_file()]
仅匹配某种后缀 py_files = list(Path(src).rglob('*.py'))
递归只取目录 dir_list = [p for p in Path(src).rglob('*') if p.is_dir()]
收集所有文件名(不含路径) names = [p.name for p in Path(src).rglob('*') if p.is_file()]
按后缀分组 suffix2files = defaultdict(list); [suffix2files[p.suffix].append(p) for p in Path(src).rglob('*') if p.is_file()]
最深层级文件(深度最大) depth2files = defaultdict(list); [depth2files[len(p.relative_to(src).parts)].append(p) for p in Path(src).rglob('*') if p.is_file()]; deepest = depth2files[max(depth2files)]

> rglob('*') 是 pathlib 的递归神器,返回生成器,惰性省内存;搭配列表推导即可一次性拿到结果。


6️⃣批量复制文件(pathlib + shutil)

from pathlib import Path
import shutil

# 待移动文件列表(遍历Path对象获得.txt后缀的文件)
file_tomove = list(Path("F:/file_source/").rglob("*.txt")) #注意要展开为list,否则是generator,循环只能使用一次
# 或者直接for循环遍历生成器: Path("F:/file_source/").rglob("*.txt")

destination = Path('H:/target_fold')
destination.mkdir(parents=True, exist_ok=True)  # 建目录

#1.易读,耗内存
for src in file_tomove:
    shutil.copy(src, destination / src.name)   # 同名移动
#2.节约内存,快速,不易读
for src in Path("F:/file_source/").rglob("*.txt"):
    shutil.copy(src, destination / src.name)   # 同名移动

7️⃣ 更换文件名(with_name)

src = Path('data/raw/sample.txt')
dst = src.with_name('sample_backup.txt')   # 仅改文件名,保留原父目录
src.replace(dst) #执行修改

8️⃣ 批量更换后缀(with_suffix)

from pathlib import Path
p=Path.cwd()
Path(p/"fold_Practise").mkdir(exist_ok=True)
for n in range(10):
    (p/"fold_Practise"/f"{n}file.md").touch(exist_ok=True) #创建练习用文件夹及1-10file.md文件
src=list((p/"fold_Practise").iterdir())#提取fold_practise下所有文件
          
for f in src:
		new_name=f.with_suffix(".png") # 仅改后缀,其余不变
		f.replace(new_name)  #执行修改

四、rename() 与 replace() 的区别

特性 Path.rename(target) Path.replace(target)
目标已存在时 抛出 FileExistsError 无条件覆盖
主要用途 安全移动 / 重命名 强制移动 / 覆盖式重命名
目标路径不存在时 抛出 FileNotFoundError 同样抛出 FileNotFoundError

五、常见陷阱与建议

  1. 路径对象不是字符串:与旧函数交互时使用 str(path)将其转为字符串。

  2. 性能考虑:大量文件遍历时,os.walk() 可能略快,但 pathlib 更安全可读。

  3. 异常处理示例

    try:
        shutil.copy2(Path('a.txt'), Path('b.txt'))
    except FileNotFoundError:
        print("源文件不存在。")
    except PermissionError:
        print("权限不足。")
    
  4. 一行式链式调用示例

    content = Path('data.txt').resolve().parent.joinpath('config.ini').read_text(encoding='utf-8')
    
  5. 关于 iterdir():

    # iterdir() 与 os.walk() 对比(两者都可遍历目录)
    print("Path.iterdir()(生成器,返回当前目录条目,非递归):")
    for entry in Path('project').iterdir():
        print("-", entry)
    
    print("os.walk()(递归、三层元组:dirpath, dirnames, filenames):")
    for dirpath, dirnames, filenames in os.walk('project'):
        print(dirpath, dirnames, filenames)
    
    # 小结:
    # - Path.iterdir() 返回生成器(generator),只列出当前目录下的条目(文件/子目录)
    # - os.walk() 返回**递归**遍历的三元组:更适合复杂的递归遍历需求
    # - Path.rglob('*.txt') 可以做递归匹配,通常比 os.walk 更直观、更像 Path 的风格
    
    • Path.iterdir() 返回 生成器(generator),列出当前目录下的条目(文件和子目录),非递归
    • os.walk() 返回递归遍历所需的三元组(dirpath, dirnames, filenames);若只需列出当前目录项,用 iterdir() 更直观;若需递归或控制子目录遍历,使用 os.walk()rglob() 更合适。

六、总结

  • pathlib 让路径管理更直观:对象化 + 链式操作 + 跨平台
  • 配合 shutil 可完成复制、备份、迁移任务。
  • 熟练掌握 .mkdir().touch() 是文件系统自动化脚本的核心。

延伸阅读

  • 官方文档:https://docs.python.org/3/library/pathlib.html
  • 相关模块:osshutiltempfile
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐