1. 什么是路径? #
1.1 什么是路径? #
路径就是文件或文件夹在磁盘上的"地址"。例如 C:\Users\Admin\documents\notes.txt(Windows)或 /home/user/documents/notes.txt(Linux)。
- 绝对路径:从盘符或根目录开始的完整地址,如
C:\Users\Admin\file.txt - 相对路径:相对于当前工作目录的地址,如
documents\file.txt表示"当前目录下的 documents 文件夹里的 file.txt"
1.2 为什么需要 pathlib? #
以前用 os.path.join('a', 'b', 'file.txt') 拼接路径,写法啰嗦,且不同系统路径分隔符不同(Windows 用 \,Linux 用 /)。pathlib 把路径封装成对象,用 / 运算符拼接,自动处理跨平台差异,代码更清晰易读。
通俗比喻:os.path 像用字符串拼地址,pathlib 像用"地址对象"直接操作,更直观。
2. 什么是 pathlib? #
pathlib 是 Python 3.4 引入的标准库,核心是 Path 类。你可以创建 Path 对象表示路径,然后调用方法完成各种操作(拼接、检查、读写、遍历等)。
下面从创建 Path 对象开始学习。
3. 创建 Path 对象 #
# 导入 Path 类
from pathlib import Path
# 用字符串创建路径(相对路径)
p = Path("documents/notes.txt")
# 获取当前工作目录(你运行脚本时所在的目录)
cwd = Path.cwd()
print("当前目录:", cwd)
# 获取用户主目录(Windows 下通常是 C:\Users\你的用户名)
home = Path.home()
print("主目录:", home)
# 绝对路径(Windows 示例)
abs_path = Path("C:/Users/Admin/file.txt")
print("绝对路径:", abs_path)说明:Path 接受正斜杠 / 或反斜杠 \,在 Windows 下都会正确解析。推荐用 /,跨平台更好。
4. 路径的组成部分 #
Path 对象可以方便地取出路径的各个部分:父目录、文件名、扩展名等。
# 导入 Path
from pathlib import Path
# 创建一个路径对象(可以是尚不存在的路径)
p = Path("C:/Users/Admin/documents/report.txt")
# 父目录(上一级路径)
print("父目录:", p.parent)
# 文件名(最后一部分,含扩展名)
print("文件名:", p.name)
# 主文件名(不含扩展名)
print("主名:", p.stem)
# 扩展名(含点号,如 .txt)
print("扩展名:", p.suffix)
# 修改扩展名得到新路径(不改变原路径)
new_path = p.with_suffix(".md")
print("新路径:", new_path)常用属性:parent(父目录)、name(文件名)、stem(主名)、suffix(扩展名)、with_suffix()(换扩展名)。
5. 路径拼接 #
pathlib 的亮点:用 / 运算符拼接路径,比 os.path.join 更直观。
# 导入 Path
from pathlib import Path
# 从当前目录开始拼接
base = Path(".")
# 用 / 拼接:当前目录 / data / output.txt
file_path = base / "data" / "output.txt"
print("拼接结果:", file_path)
# 也可以从已有 Path 继续拼接
parent = Path("C:/Users/Admin")
full_path = parent / "documents" / "notes.txt"
print("完整路径:", full_path)6. 检查路径是否存在及类型 #
# 导入 Path
from pathlib import Path
# 获取当前目录
p = Path.cwd()
# 检查路径是否存在
print("是否存在:", p.exists())
# 是否为目录
print("是否目录:", p.is_dir())
# 是否为文件
print("是否文件:", p.is_file())
# 是否为绝对路径
print("是否绝对路径:", p.is_absolute())
# 检查一个不存在的路径
fake = Path("不存在的文件夹/不存在的文件.txt")
print("不存在路径 exists:", fake.exists())7. 遍历目录 #
7.1 列出目录下所有内容(iterdir) #
# 导入 Path
from pathlib import Path
# 获取当前目录
current = Path.cwd()
# 遍历当前目录下的所有条目(不递归子目录)
for entry in current.iterdir():
# 判断是文件还是目录
if entry.is_file():
print(f"文件: {entry.name}")
else:
print(f"目录: {entry.name}")7.2 用模式匹配查找文件(glob) #
# 导入 Path
from pathlib import Path
# 获取当前目录
current = Path.cwd()
# 查找当前目录下所有 .py 文件(不递归)
print("当前目录下的 .py 文件:")
for f in current.glob("*.py"):
print(f" {f.name}")
# 递归查找当前目录及所有子目录下的 .py 文件
print("递归查找 .py 文件:")
for f in current.rglob("*.py"):
print(f" {f}")说明:* 表示任意字符,*.py 表示所有以 .py 结尾的文件。rglob 会递归进入子目录。
8. 读写文件 #
Path 对象提供了 read_text、write_text 等便捷方法,适合小文件。内部会自动处理打开和关闭。
8.1 写入和读取文本 #
# 导入 Path
from pathlib import Path
# 在当前目录创建/覆盖一个文件
p = Path("_demo_notes.txt")
# 写入文本(会覆盖原内容)
p.write_text("Hello, pathlib!\n这是第二行。", encoding="utf-8")
# 读取文本
content = p.read_text(encoding="utf-8")
print("文件内容:")
print(content)
# 删除演示文件
p.unlink(missing_ok=True)8.2 写入和读取二进制 #
# 导入 Path
from pathlib import Path
# 创建演示文件
p = Path("_demo_binary.bin")
# 写入二进制数据
p.write_bytes(b"\x00\x01\x02\x03")
# 读取二进制数据
data = p.read_bytes()
print("读取的字节:", data)
# 删除演示文件
p.unlink(missing_ok=True)9. 创建与删除 #
9.1 创建目录 #
# 导入 Path
from pathlib import Path
# 在当前目录下创建一个演示目录
p = Path("_demo_dir")
# 创建目录(parents=True 表示父目录不存在时一并创建)
p.mkdir(parents=True, exist_ok=True)
print("目录已创建:", p.exists())
# 删除空目录
p.rmdir()
print("目录已删除")说明:exist_ok=True 表示目录已存在时不报错;parents=True 表示自动创建缺失的父目录。
9.2 创建空文件(touch) #
# 导入 Path
from pathlib import Path
# 创建空文件(若已存在则更新修改时间)
p = Path("_demo_empty.txt")
p.touch()
print("文件已创建:", p.exists())
# 删除
p.unlink(missing_ok=True)9.3 重命名和删除文件 #
# 导入 Path
from pathlib import Path
# 先创建一个文件
p = Path("_demo_old.txt")
p.write_text("test", encoding="utf-8")
# 重命名
new_p = p.rename("_demo_new.txt")
print("重命名后:", new_p.name)
# 删除文件
new_p.unlink(missing_ok=True)说明:unlink() 删除文件;missing_ok=True 表示文件不存在时不报错(Python 3.8+)。
10. 解析绝对路径和相对路径 #
# 导入 Path
from pathlib import Path
# 相对路径
p = Path("documents/notes.txt")
# 解析为绝对路径(基于当前工作目录)
abs_p = p.resolve()
print("绝对路径:", abs_p)
# 计算相对路径:从 base 到 p 的相对路径
base = Path.cwd()
# 例如 base 是 C:\Users\Admin,p 是 C:\Users\Admin\documents\notes.txt
# 则 relative_to(base) 得到 documents\notes.txt
try:
rel = abs_p.relative_to(base)
print("相对路径:", rel)
except ValueError:
print("无法计算相对路径(可能不在同一盘符下)")11. 与字符串互转 #
很多旧函数需要字符串路径,Path 可以轻松转换。
# 导入 Path
from pathlib import Path
# 创建 Path 对象
p = Path("documents/notes.txt")
# 转成字符串(传给需要 str 的函数)
path_str = str(p)
print("字符串形式:", path_str)
# 从字符串创建 Path
p2 = Path(path_str)
print("Path 对象:", p2)
# open() 等函数直接接受 Path,无需转换
# with open(p, 'r') as f:
# content = f.read()12. 批量修改扩展名 #
下面是一个完整可运行的示例:在临时目录创建几个文件,批量改扩展名,最后清理。
# 导入 Path
from pathlib import Path
# 创建临时目录
demo_dir = Path("_pathlib_demo")
demo_dir.mkdir(exist_ok=True)
# 创建几个 .txt 文件
for i in range(3):
(demo_dir / f"file{i}.txt").write_text(f"内容{i}", encoding="utf-8")
# 批量把 .txt 改成 .md
for f in demo_dir.glob("*.txt"):
new_name = f.with_suffix(".md")
f.rename(new_name)
print(f"重命名: {f.name} -> {new_name.name}")
# 清理:删除所有 .md 文件和目录
for f in demo_dir.glob("*.md"):
f.unlink()
demo_dir.rmdir()
print("演示完成,已清理")13. 总结 #
| 内容 | 要点 |
|---|---|
| 创建路径 | Path("a/b/c")、Path.cwd()、Path.home() |
| 路径部分 | parent、name、stem、suffix、with_suffix() |
| 拼接 | 用 / 运算符 |
| 检查 | exists()、is_file()、is_dir() |
| 遍历 | iterdir()、glob()、rglob() |
| 读写 | read_text()、write_text()、read_bytes()、write_bytes() |
| 创建删除 | mkdir()、touch()、unlink()、rmdir() |
记忆口诀:路径用 Path,拼接用 /,读写用 read_text 和 write_text,遍历用 glob。