从 os.path 转向 pathlib

从 os.path 转向 pathlib
ytkz从 os.path 转向 pathlib 是 Python 开发中的一个重要升级。虽然 os.path 已经服务了我们很多年,但 pathlib(自 Python 3.4 引入)采用了面向对象的设计,让代码从“字符串拼接”变成了“逻辑操作”,显著提升了代码的可读性和可维护性。
老实说,我在日常工作中,使用os.path更多,但是有必要学习一下pathlib,于是有了这篇文章。这也方便小白日后学习、查询。
以下是从 os.path 过渡到 pathlib 的核心指南。
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 不仅仅是换个写法,更是一种思维的转变。会发现代码中的括号变少了,逻辑变得更加线性。






