page contents

还在拼路径字符串?pathlib 让你的 Python 代码优雅 10 倍

还在用 os.path.join 一层层拼路径?Python 内置的 pathlib 把路径变成对象:用 / 就能拼接,读写文件不用 open,找文件不用写循环。10 分钟吃透它,文末附可直接运行的实战案例。

attachments-2026-09-4WJP1yHQ6a9626f42a2a3.png

还在用 os.path.join 一层层拼路径?Python 内置的 pathlib 把路径变成对象:用 / 就能拼接,读写文件不用 open,找文件不用写循环。10 分钟吃透它,文末附可直接运行的实战案例。

一、os.path 到底有多难受

先看一段再熟悉不过的代码——拼接一个日志文件路径:

import os.path

log_dir = os.path.join(os.path.join("/data", "logs"), "app.log")
parent = os.path.dirname("/data/logs/app.log")
name = os.path.basename("/data/logs/app.log")

问题在哪?

· join 套 join,层级一深就嵌套成“俄罗斯套娃”;

· 取文件名、取父目录、取后缀,要用 basename / dirname / splitext 三个不同函数;

· 本质上,路径被当成了普通字符串——但路径明明有自己的结构(父目录、文件名、后缀),用字符串方法处理它,既脆弱又别扭。

其实 Python 3.4 起,标准库就给出了答案:pathlib。它把路径抽象成对象,上面那坨代码可以直接变成:

from pathlib import Path

log = Path("/data") / "logs" / "app.log"
print(log)        # /data/logs/app.log

就这么简单。下面带你过一遍日常最高频的四个用法,所有代码都可直接运行。

二、四个高频用法

1. 用 / 拼路径

Path 对象重载了除号运算符,拼路径像写除法算式一样自然:

from pathlib import Path

log = Path("/data") / "logs" / "app.log"
print(log)        # /data/logs/app.log

home = Path.home()          # 当前用户主目录
conf = home / ".config" / "app.ini"
print(conf)      # /root/.config/app.ini(随用户而变)

注意:/ 左边必须至少有一个 Path 对象,纯字符串之间不能直接拼接。

2. 路径信息,属性一把抓

不再需要 basename / dirname / splitext 三件套,全部变成属性访问:

from pathlib import Path

p = Path("/data/logs/app.log")
print(p.name)     # app.log —— 完整文件名
print(p.stem)     # app —— 文件名(不含后缀)
print(p.suffix)   # .log —— 后缀
print(p.parent)   # /data/logs —— 父目录
print(p.exists()) # False —— 是否存在

3. 读写小文件,一行搞定

读配置、写结果这种小文件操作,不用再写 with open(...):

from pathlib import Path

f = Path("/tmp/note.txt")
f.write_text("hello pathlib", encoding="utf-8")
print(f.read_text(encoding="utf-8"))   # hello pathlib

创建多级目录也一样省事,parents=True 自动补齐每一层,exist_ok=True 目录已存在也不报错:

Path("/tmp/demo/a/b/c").mkdir(parents=True, exist_ok=True)

4. 找文件:glob 两行搞定

想批量找文件,不用 os.walk 手写循环:

from pathlib import Path

root = Path("/data/project")
# 当前目录下的所有 Markdown 文件
for md in root.glob("*.md"):
    print(md)

# 递归查找所有 Python 文件(** 匹配任意层级子目录)
for py in root.glob("**/*.py"):
    print(py)

# 等价简写:rglob
for py in root.rglob("*.py"):
    print(py)

三、实战:10 行代码整理下载文件夹

场景:下载文件夹里图片、文档乱成一锅粥,按后缀自动归类。完整代码可直接运行:

from pathlib import Path
import shutil

src = Path("/tmp/organize_demo")   # 换成你的 Downloads 目录
ext_map = {".jpg": "images", ".png": "images", ".pdf": "docs"}

for f in src.iterdir():            # 遍历目录下所有条目
    if f.is_file():                # 只处理文件,跳过子目录
        target = src / ext_map.get(f.suffix, "others")
        target.mkdir(exist_ok=True)
        shutil.move(str(f), target / f.name)

运行后,a.jpg、b.png 进 images/,c.pdf 进 docs/,其余进 others/。逐行拆解:

· iterdir() 拿到目录下每个条目的 Path 对象;

· f.suffix 取后缀,查 ext_map 得到目标子目录名;

· target / f.name 拼出目标完整路径——又是 / 运算符的功劳。

换成 os.path 写,光是拼接和拆后缀就得多写好几行中间变量。

四、版本兼容提醒

pathlib 自 Python 3.4 引入(PEP 428),本文用到的 read_text / write_text / glob 等方法在 Python 3.6 及以上全部可用,直接 import 无需安装任何第三方库。

一点小提醒:更新的 API 如递归遍历 Path.walk() 要 3.12+ 才有,团队还在用老版本 Python 的话,优先用文中这些“长寿”API,兼容性最好。

写在最后

pathlib 的设计哲学就一句话:路径不是字符串,是对象。一旦习惯这个思维,你会发现 os.path 那套函数式调用再也回不去了。

建议从今天开始:新代码一律 from pathlib import Path,旧代码碰到路径逻辑时顺手迁移。一个小改变,代码可读性立竿见影。

更多相关技术内容咨询欢迎前往并持续关注好学星城论坛了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg

 

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

2372 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. Pack 2372 文章
  3. 小柒 2228 文章
  4. Nen 576 文章
  5. 王昭君 216 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章