应使用 path("a") / "b" / "c" 拼接路径,避免字符串拼接;exists() 与 is_file() 连用存在竞态条件,推荐直接 try: read_text() except filenotfounderror;glob() 注意隐藏文件和大小写兼容性;resolve() 在权限受限时易失败,日常用 absolute() 更安全。

pathlib.Path() 初始化时别用字符串拼接
直接用 Path("a") / "b" / "c",别写 Path("a/b/c") 或更糟的 Path("a" + os.sep + "b" + os.sep + "c")。前者自动处理平台差异(\ vs /),后者在 Windows 上可能因反斜杠转义出错,比如 "C:\temp\file.txt" 里 \t 被当制表符解析。
常见错误现象:FileNotFoundError 却提示路径看起来“没错”;或在 CI(Linux)上跑通,本地(Windows)报错。
- 永远用
/运算符拼路径,它是Path的重载方法,语义清晰且安全 - 如果必须从字符串构造,优先用
Path.cwd() / "subdir" / filename,而非拼完整字符串 - 读配置或用户输入的路径字符串,先用
Path(path_str).resolve()归一化,避免相对路径残留
exists() 和 is_file() 别连用,也别代替 try/except
exists() 只告诉你路径是否存在,is_file() 还得确认是文件(不是目录、符号链接或权限不足)。但这两者之间存在竞态条件:路径可能在两次调用之间被删掉或改类型。更糟的是,有人用 if p.exists() and p.is_file(): p.read_text(),这比直接 try: p.read_text() except FileNotFoundError: 多一次系统调用,还更不可靠。
使用场景:脚本需要读取配置文件、加载模板、检查日志是否存在——这些都该用异常捕获,而不是预检。
立即学习“Python免费学习笔记(深入)”;
- 99% 的情况,直接
try: content = p.read_text() except FileNotFoundError:更简洁、更健壮 - 只有当你需要区分“不存在”和“是目录但非文件”时,才用
is_file(),且务必配合exists()一起用(exists()返回False时is_file()也返回False,但不报错) -
is_symlink()、is_dir()同理,不要链式判断,要按实际需求选一个语义明确的方法
glob() 和 rglob() 的模式匹配容易忽略点号和大小写
Path("logs").glob("*.log") 不会匹配 .access.log,因为 * 默认不匹配开头的点;rglob("**/*.py") 在 macOS 或 Linux 上默认大小写敏感,但 Windows 文件系统不区分大小写,所以 script.PY 可能漏掉。
性能影响:用 ** 递归太深会变慢,尤其在大项目中遍历 node_modules 或 __pycache__ 目录时。
- 要匹配隐藏文件,显式写
glob(".*.log")或用iterdir()+ 手动过滤 - 跨平台确保大小写兼容,用
glob("*.py")后加str(p).lower().endswith(".py")过滤,或者用正则配合match() - 避免无限制
**,优先用iterdir()分层遍历,或加max_depth参数(需自己实现,pathlib原生不支持)
resolve() 在符号链接和权限边界上行为不稳定
resolve() 会跟随符号链接并展开 ..,但它在遇到权限不足的父目录时直接抛 PermissionError,而不是跳过。更隐蔽的是:如果路径本身存在但上级某目录不可读,resolve() 就失败,而 exists() 却可能返回 True(因为路径存在,只是你没权限看全路径)。
兼容性影响:Python 3.6+ 行为统一,但旧版(如 3.4)对 resolve(strict=False) 支持不全,容易误用。
- 仅当明确需要绝对路径且能保证全程可访问时,才用
resolve() - 日常获取绝对路径,用
absolute()更轻量,它不检查路径是否存在也不跟随符号链接 - 处理用户传入路径时,先
Path(user_input).expanduser().resolve(strict=False),再手动检查关键段是否可访问,比硬刚resolve()更可控









