绝对路径不依赖当前工作目录,因其基于文件系统根目录动态计算(如path(__file__).resolve().parent),而相对路径依赖os.getcwd()导致跨环境失效;硬编码绝对路径不可移植,应锚定脚本位置。

绝对路径不依赖当前工作目录
根本原因在于:os.path.abspath() 或 pathlib.Path.resolve() 生成的路径,是基于文件系统根目录算出来的完整路径,和你在哪个目录下执行 python script.py 完全无关。而相对路径(比如 "data/config.json")会被解释器自动拼上 os.getcwd() 的结果——一旦你从项目根目录外运行脚本,拼出来的路径就错位了。
常见错误现象:FileNotFoundError: [Errno 2] No such file or directory: 'data/config.json',但你明明看到文件就在旁边。实际是脚本在 /home/user 下运行,却去 /home/user/data/config.json 找,而不是 /home/user/myproject/data/config.json。
- 绝对路径直接锁定位置,不随
cd改变 - 它绕过了“当前工作目录”这个不稳定变量
- 对 CI/CD、Docker 容器、定时任务等非交互式环境尤其关键
但硬编码绝对路径为什么也不行?
写死 "/Users/renhai/project/data/config.txt" 看似解决问题,实则把路径耦合到某台机器上。同事拉代码后一运行就崩,因为路径里有他电脑上不存在的用户名和盘符。
真正可用的“绝对路径”,必须是动态计算出来的,且锚定在脚本自身位置。核心就是利用 __file__:
-
os.path.abspath(__file__)→ 当前脚本的绝对路径(含文件名) -
os.path.dirname(os.path.abspath(__file__))→ 当前脚本所在目录 -
pathlib.Path(__file__).resolve().parent→ 更推荐,自动处理跨平台斜杠和符号链接
示例:
from pathlib import Path<br>config_path = Path(__file__).resolve().parent / "data" / "config.json"这样无论脚本被放在哪、从哪运行,只要
data/config.json 相对于脚本的位置不变,就能找到。
打包成 exe 后 __file__ 还可靠吗?
不可靠——PyInstaller 等工具打包后,__file__ 指向的是临时解压目录(如 /tmp/_MEIxxx/),不是源码位置。此时硬靠 __file__ 会找不到资源文件。
解决办法分两种场景:
- 资源文件跟代码一起打包:用
sys._MEIPASS(PyInstaller)或pkg_resources.resource_filename()(setuptools)获取运行时真实路径 - 资源文件放外部(如配置文件允许用户修改):改用环境变量或命令行参数传入路径,不依赖脚本位置
别指望 os.getcwd() + __file__ 拼接,这种写法在任何环境下都危险,因为 os.getcwd() 和 __file__ 的基准点根本不同。
什么时候其实该用相对路径?
不是所有地方都要转绝对路径。比如模块导入:from ..utils.helper import load_config 是合法且合理的相对导入,前提是整个目录是 Python 包(有 __init__.py),且通过 python -m package.module 运行。
但文件读写操作几乎从不用纯相对路径,除非你明确控制并固定了工作目录(例如在 Makefile 或 CI 脚本里先 cd 到项目根目录再运行)。否则,那个“相对”的基准点本身就是个幻觉。
最易被忽略的点:很多人以为 os.path.abspath("data/") 就够用了,却没意识到它仍依赖 os.getcwd()。真正健壮的做法,永远以 __file__ 为起点做偏移,而不是以当前目录为起点。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











