Python怎么获取脚本文件所在的绝对路径

拾柒
拾柒
发布时间:2026-11-06| 7人浏览过
原创

详细讲解在Python中如何准确获取当前脚本文件所在的绝对路径,对比pathlib与os.path的用法,解析工作目录与脚本目录的本质区别,以及符号链接与特殊运行环境下的避坑要点。

在 Python 中,获取当前脚本文件所在的绝对路径最推荐的标准做法是使用现代内置模块 pathlib:通过 Path(__file__).resolve() 获取脚本自身的绝对文件路径,调用 .parent 属性即可得到脚本所在的目录绝对路径;如果需要兼顾 Python 2 或习惯使用传统内置模块,则可以使用 os.path.dirname(os.path.abspath(__file__))。
Python怎么获取脚本文件所在的绝对路径 图 1:Python 获取脚本自身所在绝对路径的两种标准方案速览

一、为什么不能直接用 os.getcwd()?

很多初学者在编写读取配置、加载同级资源文件的代码时,习惯性调用 os.getcwd() 或 Path.cwd()。这种写法在本地测试、且终端正好处于脚本所在文件夹运行时通常能够正常工作,但一旦项目被部署、作为系统定时任务(如 crontab)、或者在不同工作目录下被调用时,程序就会立刻报出 FileNotFoundError。

产生这一现象的根源在于:“当前工作目录”(Current Working Directory)与“脚本文件所在目录”(Script Directory)是完全不同的两个概念:

  • 当前工作目录(CWD):是终端执行 Python 解释器时所在的目录。用户在哪个路径下输入 python ...,CWD 就是哪里。它是动态变化的。
  • 脚本文件所在目录:是 .py 脚本文件在磁盘中固定的存储位置,无论外部从哪个文件夹发起调用,它都是确定的。
Python怎么获取脚本文件所在的绝对路径 图 2:当前工作目录(CWD)与脚本所在文件目录的差异与寻址影响

二、现代推荐方案:使用 pathlib 模块

从 Python 3.4 开始,标准库引入了面向对象的 pathlib 模块。在 Python 3 中编写新代码时,应优先使用 pathlib。它摆脱了繁杂的字符串拼接,语法清晰易读。

1. 获取脚本文件自身及所在目录的绝对路径

在你的脚本中,只需写下如下几行:

from pathlib import Path

# 获取当前脚本文件的绝对路径(指向 .py 文件本身)
script_path = Path(__file__).resolve()

# 获取当前脚本文件所在的目录的绝对路径(指向包含该脚本的文件夹)
script_dir = script_path.parent

print("脚本文件绝对路径:", script_path)
print("脚本所在目录路径:", script_dir)
示例输出
脚本文件绝对路径: /Users/alice/projects/demo/main.py
脚本所在目录路径: /Users/alice/projects/demo
Python怎么获取脚本文件所在的绝对路径 图 3:pathlib 链式调用各阶段的内部行为与返回值变化

2. 实用延伸:基于脚本目录安全拼接项目文件

获取脚本绝对目录后,最常见的需求是定位项目的配置文件、日志目录或数据包。pathlib 提供了重载的斜杠 / 运算符,让路径拼接非常自然,再也不用手动处理 Windows \ 与 Linux / 的差异:

from pathlib import Path

# 当前脚本所在目录
BASE_DIR = Path(__file__).resolve().parent

# 拼接同级或子目录资源文件
config_file = BASE_DIR / "config.json"
data_dir = BASE_DIR / "assets" / "images"

print("配置文件绝对路径:", config_file)
print("配置文件是否存在:", config_file.exists())

三、传统兼容方案:使用 os.path 模块

在旧项目维护、或者需要兼容老版本 Python 环境中,os.path 依然是最普遍的写法。它主要通过组合 os.path.abspath 和 os.path.dirname 实现。

import os

# 1. 获取脚本文件本身的绝对路径
script_file_path = os.path.abspath(__file__)

# 2. 获取脚本所在目录的绝对路径
script_dir_path = os.path.dirname(script_file_path)

# 也可以直接缩写为一行
script_dir = os.path.dirname(os.path.abspath(__file__))

print("脚本文件绝对路径:", script_file_path)
print("脚本所在目录路径:", script_dir)
调用顺序的讲究:为什么先 abspath 再 dirname?

虽然有时写 os.path.abspath(os.path.dirname(__file__)) 也能得到正确结果,但最佳顺序是先对 __file__ 执行 os.path.abspath。原因在于当通过 python test.py 直接运行当前目录脚本时,__file__ 的值是纯文件名 'test.py',此时如果先调 os.path.dirname('test.py') 会返回空字符串 '',虽然随后的 abspath('') 恰好会回退为当前工作目录,但逻辑不够直观严密。

四、关键细节与边界场景避坑

绝大多数常规脚本中使用上述方法已经足够稳健,但在以下三个特殊场景中,需要特别注意代码的执行边界。

Python怎么获取脚本文件所在的绝对路径 图 4:符号链接解析差异与特殊运行环境下的处理要点

1. 符号链接(软链接)的处理:resolve 与 absolute 的区别

如果你的脚本是通过 Linux 软链接(ln -s)部署运行的,你需要明确自己想要的是“软链接所在的位置”还是“源文件真正所在的位置”:

  • Path(__file__).resolve()(对应 os.path.realpath(__file__)):会追溯并解析软链接,返回真实源文件的绝对路径。绝大多数需要加载源码同级资源包的场景都应使用此方法。
  • Path(__file__).absolute()(对应 os.path.abspath(__file__)):不会解析符号链接,返回的是符号链接本身的路径。

2. 交互式解释器与 Jupyter Notebook

在 Python 交互式命令行(REPL)、python -c "..." 或是 Jupyter Notebook 单元格中执行代码时,是不存在 __file__ 这个全局变量的,直接访问会触发 NameError: name '__file__' is not defined。如果需要写出兼容两者的健壮代码,可以使用如下封装:

import sys
from pathlib import Path

def get_script_dir():
    # 检查全局作用域中是否存在 __file__
    if "__file__" in globals():
        return Path(__file__).resolve().parent
    # 交互式环境回退到当前工作目录
    return Path.cwd()

current_dir = get_script_dir()
print("当前安全目录:", current_dir)

3. PyInstaller 打包后的路径获取

当你使用 PyInstaller 将 Python 脚本打包为单文件可执行程序时,程序运行时会将资源解压到操作系统的临时目录(sys._MEIPASS)。此时如果你希望获取可执行文件(.exe)所在的真实目录(比如读取 exe 同级下的外部配置文件),应该使用 sys.executable:

import sys
from pathlib import Path

def get_app_dir():
    # 判断是否运行在 PyInstaller 冻结环境中
    if getattr(sys, "frozen", False):
        return Path(sys.executable).resolve().parent
    return Path(__file__).resolve().parent

APP_DIR = get_app_dir()
print("应用基准目录:", APP_DIR)

五、方法选型与总结

获取脚本绝对路径的核心在于以 __file__ 为锚点,将其从启动时的相对表达解析为磁盘上的绝对物理位置。以下是常见 API 的对比速查:

实现方式 脚本所在目录写法 返回值类型 推荐指数 / 适用场景
pathlib (首选) Path(__file__).resolve().parent Path 对象 ★★★★★ Python 3.4+ 现代代码推荐,语法优雅,跨平台友好
os.path (经典) os.path.dirname(os.path.abspath(__file__)) str 字符串 ★★★★☆ 兼容 Python 2 或老旧工程
软链接源路径 Path(__file__).resolve().parent Path 对象 ★★★★★ 穿透软链接,准确定位真实代码位置
打包应用兼顾 根据 getattr(sys, 'frozen', False) 分支处理 Path 对象 ★★★★★ 桌面软件发布、CLI 二进制分发场景
Python怎么获取脚本文件所在的绝对路径 图 5:获取脚本绝对路径的完整技术路线与选择决策

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。