__file__ 不是绝对路径,需用 Path(__file__).resolve() 获取真实绝对路径;直接 os.path.dirname(__file__) 可能返回相对路径,导致拼接错误。

为什么 __file__ 不能直接当绝对路径用
很多新手一上来就写 os.path.dirname(__file__),以为这就拿到了脚本所在目录的绝对路径——其实不是。如果 Python 是从其他目录启动(比如 python /tmp/project/main.py),__file__ 的值是相对路径或不含前缀的路径,os.path.dirname 返回的也可能是相对路径,后续拼接文件时容易出错。
关键点:必须显式做「路径解析」才能得到稳定可靠的绝对路径。
-
pathlib.Path(__file__).resolve()是最安全的做法,它会解析符号链接、补全相对路径、返回真正的绝对路径 - 如果只需要目录,用
pathlib.Path(__file__).resolve().parent,比os.path.dirname(os.path.abspath(__file__))更简洁、可读性更强 - 注意
.resolve()会真实访问文件系统,若__file__对应的文件已被删除或移动,会抛FileNotFoundError
用 pathlib.Path 拼接配置文件路径时的常见错误
想读取同级的 config.json,有人这么写:Path(__file__).parent / "config.json" —— 看似没问题,但没加 .resolve(),一旦脚本被软链接调用,.parent 指向的是链接所在目录,不是源文件目录。
正确做法是先 resolve 再 parent:
立即学习“Python免费学习笔记(深入)”;
from pathlib import Path config_path = Path(__file__).resolve().parent / "config.json"
- 用
/拼接路径是pathlib的核心优势,不用再记os.path.join的参数顺序 - 如果项目结构是脚本在
src/下,配置在项目根目录,别硬写../config.json,改用Path(__file__).resolve().parent.parent / "config.json" -
Path(...).exists()和.is_file()比os.path.exists()更直观,建议优先使用
pathlib 在跨平台路径处理中的实际差异
Windows 和 Linux 对路径分隔符、盘符、大小写的处理不同,os.path 很多函数(如 os.path.normpath)行为不一致;pathlib 抽象层统一了这些逻辑。
-
Path("a/b/c").as_posix()总是返回"a/b/c"(正斜杠),适合日志打印或 HTTP 路径构造 -
Path("C:\temp\file.txt").as_posix()返回"C:/temp/file.txt",避免 Windows 下反斜杠引发的字符串转义问题 - 路径比较时,
Path("A.txt") == Path("a.txt")在 Windows 上为True,Linux 上为False,这和系统行为一致,无需额外适配
什么时候还不得不回退到 os.path
pathlib 覆盖了绝大多数场景,但仍有几个边缘情况目前没替代方案:
- 获取当前工作目录的原始字符串(
os.getcwd()),Path.cwd()虽然等价,但返回的是Path对象,某些旧 API 只接受str - 需要控制
os.path.expanduser("~")或expandvars("$HOME")时,pathlib没有对应方法,得先用os.path处理再转成Path - 性能敏感的循环内频繁拼路径(如百万次日志路径生成),
os.path.join略快于Path / Path,但差距通常在纳秒级,除非压测确认是瓶颈,否则不必降级
真正容易被忽略的是:Path(__file__) 本身不触发任何文件系统访问,但只要调用 .resolve()、.exists()、.stat() 这类方法,就会真实发起系统调用——在容器或网络文件系统中可能变慢或失败,别在模块顶层无条件执行它们。


















