pathlib.path比os.path更直观,但不可直接替换所有旧代码;需注意path对象非字符串、须显式转str,链式操作和路径构造更简洁,glob/iterdir用途不同,类型判断需exists()与is_file()/is_dir()连用,open()需手动建父目录并指定encoding。

pathlib.Path比os.path更直观,但别直接替换所有旧代码
直接把 os.path.join() 全换成 Path() 拼接,大概率会出错——Path 对象不是字符串,很多老接口(比如 open()、subprocess.run())不接受它。得显式调用 str() 或用 .resolve()/.absolute() 转成路径字符串,否则报 TypeError: expected str, bytes or os.PathLike object。
真正省事的地方是链式操作:比如获取上两级父目录再进 config 子目录,Path(__file__).parent.parent / "config" 比 os.path.join(os.path.dirname(os.path.dirname(__file__)), "config") 清晰得多。
- 推荐只在路径构造、遍历、检查场景用
Path,涉及外部命令或老库调用时加str() -
/运算符重载是安全的,自动处理分隔符(Windows 用\,Linux/macOS 用/),不用再记os.sep -
Path.cwd()和Path.home()比os.getcwd()和os.path.expanduser("~")少写一截
glob() 和 iterdir() 别混用:前者支持通配符,后者只列一层子项
Path.iterdir() 是最基础的目录遍历,只返回当前目录下所有直接子项(文件+目录),不递归,也不支持 * 或 **。想查所有 .py 文件?得用 Path.glob("*.py");想递归找?用 Path.rglob("**/*.py")。
注意 glob() 返回的是生成器,不是列表,多次遍历时要重新调用;如果需要缓存结果,得包一层 list()。
-
Path("src").iterdir()→ 直接子项,无过滤 -
Path("src").glob("*.py")→ 当前层所有.py文件 -
Path("src").rglob("test_*.py")→ 所有子目录中匹配的测试文件 - 匹配失败时,
glob()返回空生成器,不会抛异常,记得用next(..., None)安全取第一个
exists()、is_file()、is_dir() 这三个判断必须连用,单独用有陷阱
Path.exists() 只说明路径存在(可能是文件、目录、符号链接甚至挂起的网络设备),但它不区分类型;而 is_file() 和 is_dir() 在路径不存在时一律返回 False,不是抛异常。所以常见错误是只写 if p.is_file():,结果路径根本不存在也静默跳过。
正确做法是先 exists(),再判类型;或者用 is_file() and p.exists()(虽然略冗余,但语义明确)。
-
p = Path("data.csv"); p.exists() and p.is_file()→ 确保是真实存在的普通文件 -
p.is_symlink()要单独判断符号链接,它和is_file()不互斥(链接指向文件时两者都为True) -
is_absolute()比os.path.isabs()更直白,但要注意Path("a/b")默认是相对路径,即使当前在根目录下
读写文件时,Path.open() 要小心默认编码和缺失的parent创建
Path.open() 是便捷封装,但默认以文本模式打开且使用系统默认编码(可能不是 UTF-8),中文路径或内容容易乱码;另外它不会自动创建父目录——如果 Path("logs/app.log") 的 logs/ 不存在,直接 .open("w") 会报 FileNotFoundError。
安全写法是:先 p.parent.mkdir(parents=True, exist_ok=True),再 p.open("w", encoding="utf-8")。读文件同理,encoding 显式指定更稳妥。
-
Path("out.txt").write_text("hello", encoding="utf-8")自动处理编码和换行,比open().write()少两行 -
write_bytes()和read_bytes()用于二进制数据,不碰编码 -
touch()创建空文件时,同样要确保父目录存在,否则加exist_ok=True也没用,得提前建目录
最常被忽略的是路径解析时机:Path("data") / "file.txt" 是惰性拼接,不检查磁盘;直到调用 .exists()、.open() 或 .resolve() 才真正访问文件系统。调试时如果路径拼错了,错误会延迟到实际使用才暴露。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











