集成电路科普者 2025-10-09 15:50 采纳率: 98.5%
浏览 2
已采纳

pd.read_excel相对路径跨目录读取失败

使用 `pd.read_excel` 时,通过相对路径跨目录读取 Excel 文件常因工作目录与脚本位置不一致导致文件找不到。例如,在项目结构中调用 `../data/file.xlsx` 时,若当前工作目录未正确设置,Python 将无法定位文件,抛出 `FileNotFoundError`。该问题在不同操作系统或IDE间尤为明显,根源在于相对路径依赖运行时上下文,而非脚本所在目录。
  • 写回答

1条回答 默认 最新

  • 羽漾月辰 2025-10-09 15:50
    关注

    1. 问题现象与常见错误场景

    在使用 pd.read_excel("../data/file.xlsx") 时,开发者常遇到 FileNotFoundError。该异常的根本原因在于:相对路径是相对于当前工作目录(Current Working Directory, CWD)解析的,而非脚本文件所在的目录。

    Traceback (most recent call last):
      File "scripts/process_data.py", line 3, in <module>
        df = pd.read_excel("../data/file.xlsx")
      File "pandas/io/excel/_base.py", line 456, in read_excel
        io = ExcelFile(io, engine=engine)
      File "pandas/io/excel/_base.py", line 1176, in __init__
        self._reader = self._engines[engine](self._io)
      FileNotFoundError: [Errno 2] No such file or directory: '../data/file.xlsx'
    
    • 在 PyCharm 中运行脚本时,CWD 默认为项目根目录,可能成功。
    • 在命令行中从其他目录启动脚本,则失败。
    • Jupyter Notebook 中执行时,路径行为更加不可预测。

    2. 根源分析:工作目录 vs 脚本位置

    对比维度当前工作目录 (os.getcwd())脚本所在目录 (__file__)
    获取方式os.getcwd()os.path.dirname(__file__)
    可变性运行时动态变化
    固定(基于脚本物理位置)
    IDE影响高度依赖(如VSCode、PyCharm设置不同)不受影响
    跨平台一致性

    3. 解决方案层级演进

    1. 临时修复:手动设置工作目录
    2. 基础改进:利用 __file__ 动态构建路径
    3. 工程化方案:引入 pathlib 实现跨平台兼容
    4. 架构级设计:配置中心化 + 环境感知路径管理

    4. 推荐实现代码示例

    import pandas as pd
    from pathlib import Path
    
    # 获取脚本所在目录
    SCRIPT_DIR = Path(__file__).parent.resolve()
    
    # 构建跨目录的稳定路径
    EXCEL_FILE = SCRIPT_DIR.parent / "data" / "file.xlsx"
    
    # 安全读取
    if EXCEL_FILE.exists():
        df = pd.read_excel(EXCEL_FILE)
    else:
        raise FileNotFoundError(f"文件未找到: {EXCEL_FILE}")
    

    5. 高级路径管理策略

    graph TD A[调用 pd.read_excel] --> B{路径是否相对?} B -- 是 --> C[解析相对路径] C --> D[基于 __file__ 定位脚本目录] D --> E[使用 pathlib 合并路径] E --> F[验证文件是否存在] F --> G[执行读取操作] B -- 否 --> H[直接尝试读取] H --> I[捕获异常并记录]

    6. 多环境兼容性处理

    在 Windows、macOS 和 Linux 上,路径分隔符和权限模型存在差异。使用 pathlib.Path 可自动适配:

    • Windows: C:\project\data\file.xlsx
    • Unix-like: /home/user/project/data/file.xlsx
    • Path 抽象层屏蔽了底层差异
    # 兼容性测试片段
    def get_data_path(filename: str) -> Path:
        return (Path(__file__).parent.parent / "data" / filename).resolve()
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 10月23日
  • 创建了问题 10月9日