os.getcwd() 不可靠,因它返回执行时的当前工作目录而非脚本所在目录;应使用 os.path.dirname(os.path.abspath(__file__)) 获取脚本绝对路径。

为什么 os.getcwd() 不可靠
在独立脚本里调用 os.getcwd() 返回的是“当前工作目录”,不是脚本所在目录。比如你在 /home/user 下执行 python /tmp/myscript.py,os.getcwd() 是 /home/user,但脚本实际在 /tmp。这会导致后续用相对路径读配置、加载资源时出错。
__file__ 是唯一可信的起点
Python 解释器启动时会把当前执行文件的路径赋给 __file__,它始终是脚本的磁盘路径(可能是相对路径,也可能是绝对路径)。关键是要把它标准化:
- 用
os.path.abspath(__file__)强制转成绝对路径(推荐 Python 3.4+) - 或用
pathlib.Path(__file__).resolve()更现代、跨平台 - 避免只用
os.path.dirname(__file__)—— 如果__file__是相对路径,结果仍是相对的
示例:
import os<br>script_dir = os.path.dirname(os.path.abspath(__file__))<br>print(script_dir) # 比如 /home/user/project/utils
注意 PyInstaller 和打包后的行为差异
当用 PyInstaller 打包成单文件(--onefile)时,__file__ 指向临时解压路径(如 /tmp/_MEIxxx/xxx.py),不是原始开发路径。这时要改用:
立即学习“Python免费学习笔记(深入)”;
-
sys._MEIPASS(PyInstaller 特有)获取资源根目录 - 判断是否打包:
getattr(sys, 'frozen', False) - 组合逻辑:
base_path = sys._MEIPASS if getattr(sys, 'frozen', False) else os.path.dirname(os.path.abspath(__file__))
别混淆模块路径和包路径
如果你的脚本是作为模块被导入(比如 python -m mypackage.myscript),__file__ 依然有效;但 __package__ 或 __name__ 无法反推出磁盘路径。不要试图用 importlib.resources 或 pkgutil.get_data 去“找脚本自身位置”——它们面向的是已安装包,对独立脚本不适用,且在未安装状态下会失败。
最简、最稳的写法就一句:os.path.dirname(os.path.abspath(__file__)),其余都是为特殊部署场景打的补丁。


















