从 os.path 转向 pathlib

os.path 转向 pathlib 是 Python 开发中的一个重要升级。虽然 os.path 已经服务了我们很多年,但 pathlib(自 Python 3.4 引入)采用了面向对象的设计,让代码从“字符串拼接”变成了“逻辑操作”,显著提升了代码的可读性和可维护性。

老实说,我在日常工作中,使用os.path更多,但是有必要学习一下pathlib,于是有了这篇文章。这也方便小白日后学习、查询。

以下是从 os.path 过渡到 pathlib 的核心指南。

High-level Path Operations Using pathlib Module In Python - GeekPython -  Python Programming Tutorials

1. 核心哲学:字符串 vs 对象

os.path: 将路径视为字符串。你需要不断调用函数并传入这些字符串。

pathlib: 将路径视为对象。路径本身拥有属性(文件名、后缀)和方法(合并、移动、读取)。

基础导入:

import os
from pathlib import Path

2. 常用操作对照表

这是最直观的迁移参考,涵盖了 90% 的日常使用场景。

操作类型 os.path / os pathlib (Path 对象)
获取当前工作目录 os.getcwd() Path.cwd()
当前用户的主目录 os.path.expanduser(“~”) Path.home()
路径拼接 os.path.join(a, b) a / b
获取文件名 os.path.basename(p) p.name
获取父目录 os.path.dirname(p) p.parent
获取文件后缀 os.path.splitext(p)[1] p.suffix
获取无后缀文件名 os.path.split(p)[1].split(‘.’)[0] p.stem
判断文件是否存在 os.path.exists(p) p.exists()
创建目录 os.makedirs(p, exist_ok=True) p.mkdir(parents=True, exist_ok=True)
判断是否为文件 os.path.isfile(p) p.is_file()

os.path 转向 pathlib 是 Python 开发中的一个重要升级。虽然 os.path 已经服务了我们很多年,但 pathlib(自 Python 3.4 引入)采用了面向对象的设计,让代码从“字符串拼接”变成了“逻辑操作”,显著提升了代码的可读性和可维护性。

以下是从 os.path 过渡到 pathlib 的核心指南。


1. 核心哲学:字符串 vs 对象

  • os.path: 将路径视为字符串。你需要不断调用函数并传入这些字符串。
  • pathlib: 将路径视为对象。路径本身拥有属性(文件名、后缀)和方法(合并、移动、读取)。

基础导入

Python

import os
from pathlib import Path

2. 常用操作对照表

这是最直观的迁移参考,涵盖了 90% 的日常使用场景。

操作类型 os.path / os pathlib (Path 对象)
获取当前工作目录 os.getcwd() Path.cwd()
获取用户家目录 os.path.expanduser("~") Path.home()
路径拼接 os.path.join(a, b) a / b
获取文件名 os.path.basename(p) p.name
获取父目录 os.path.dirname(p) p.parent
获取文件后缀 os.path.splitext(p)[1] p.suffix
获取无后缀文件名 os.path.split(p)[1].split('.')[0] p.stem
判断文件是否存在 os.path.exists(p) p.exists()
判断是否为文件 os.path.isfile(p) p.is_file()
创建目录 os.makedirs(p, exist_ok=True) p.mkdir(parents=True, exist_ok=True)

3. 深度对比:为什么 pathlib 更好?

路径拼接:告别冗长的 join

使用 os.path 拼接多层路径时,嵌套的括号非常痛苦。pathlib 重载了 / 运算符,让路径书写像文件系统一样直观。

  • 旧写法: os.path.join('home', 'user', 'config.ini')
  • 新写法: Path('home') / 'user' / 'config.ini'

下面是具体的例子:

from pathlib import Path

# 基本拼接
base_path = Path("/home/user")
sub_dir = "documents"
file_name = "file.txt"
full_path = base_path / sub_dir / file_name
print(full_path)  # 输出:/home/user/documents/file.txt

# 混合拼接:Path对象与字符串
path1 = Path("folder1")
path2 = "folder2"
result = path1 / path2
print(result)  # 输出:folder1/folder2(或folder1\folder2,取决于操作系统)

路径拆解:更直观的属性

假设有一个路径 /usr/local/bin/python.exe

  • p.name: python.exe (完整文件名)
  • p.stem: python (不含后缀)
  • p.suffix: .exe (后缀)
  • p.parent: /usr/local/bin (上级目录)
  • p.anchor: / (根目录/盘符)

文件读写:一键完成

pathlib 封装了简单的读写操作,不再需要手动配合 with open()

p = Path('hello.txt')
p.write_text('Hello World')  # 直接写入字符串
content = p.read_text()       # 直接读取内容

4. 强大的文件搜索 (Glob)

os 模块中,搜索文件通常需要配合 glob 库。而在 pathlib 中,这是内置功能:

# 获取当前目录下所有 .py 文件
for file in Path('.').glob('*.py'):
    print(file.name)

# 递归获取所有子目录下的图片文件
images = list(Path('src').rglob('*.jpg'))

5. 常见问题:如果库只接受字符串怎么办?

虽然现在绝大多数库(如 pandas, open(), requests)都直接支持 Path 对象,但如果你遇到一些老旧的库必须要求字符串:

p = Path('/some/path')
# 强制转换为字符串
old_api_call(str(p))

总结

os.path 切换到 pathlib 不仅仅是换个写法,更是一种思维的转变。会发现代码中的括号变少了,逻辑变得更加线性。