使用PyInstaller打包多文件夹Python项目为独立可执行文件遇路径问题
PyInstaller打包后无法找到CSV资源文件的解决方案
问题背景
项目结构:
csab: 2022: round1: some_files.csv tool.py
需打包包含csab、josaa文件夹的CSV数据文件,使用PyInstaller分别在Windows和Linux环境打包后,运行均出现CSV路径找不到的错误。
打包命令
Windows环境:
pyinstaller --noconfirm --onefile --console --add-data "E:/python/jee_counsellor/csab;csab/" --add-data "E:/python/jee_counsellor/josaa;josaa/" "E:/python/jee_counsellor/tool.py"
Linux环境:
python -m PyInstaller --onefile --add-data 'csab/*:csab' --add-data 'josaa/*:josaa' --exclude-module _tkinter tool.py
错误信息
Traceback (most recent call last): File "tool.py", line 250, in <module> File "tool.py", line 16, in pre_setup File "tool.py", line 36, in csab_rounds File "tool.py", line 54, in csv_files File "pandas\io\parsers\readers.py", line 912, in read_csv File "pandas\io\parsers\readers.py", line 577, in _read File "pandas\io\parsers\readers.py", line 1407, in __init__ File "pandas\io\parsers\readers.py", line 1661, in _make_engine File "pandas\io\common.py", line 859, in get_handle FileNotFoundError: [Errno 2] No such file or directory: 'E:\\python\\jee_counsellor\\output\\csab\\2022\\round_2\\ranks.csv' [19596] Failed to execute script 'tool' due to unhandled exception!
出错代码片段
cwd = os.getcwd() csab_rounds = round csv_path = os.path.join(cwd, "csab", "2022", f"round_{csab_rounds}", "ranks.csv") df = pd.read_csv(csv_path)
核心问题原因
os.getcwd()获取的是程序运行时的当前工作目录(比如双击exe时的桌面、用户目录),而非PyInstaller打包后资源文件的实际存放位置。使用--onefile参数打包时,PyInstaller会将所有资源临时解压到系统临时目录(Windows为%TEMP%\_MEIxxxxxx,Linux为/tmp/_MEIxxxxxx),直接用os.getcwd()拼接路径必然找不到文件。
解决方法
1. 修改代码:获取正确的资源路径
替换原路径拼接逻辑,动态适配开发环境与打包环境:
import os import sys def get_resource_path(relative_path): # 打包环境下使用临时解压目录 if hasattr(sys, '_MEIPASS'): return os.path.join(sys._MEIPASS, relative_path) # 开发环境下使用脚本所在目录的相对路径 return os.path.join(os.path.abspath(os.path.dirname(__file__)), relative_path) # 替换原路径生成代码 csv_path = get_resource_path(os.path.join("csab", "2022", f"round_{csab_rounds}", "ranks.csv")) df = pd.read_csv(csv_path)
2. 调整PyInstaller打包命令
- Windows环境:在项目根目录执行命令,无需绝对路径,确保目标路径与代码拼接逻辑一致:
pyinstaller --noconfirm --onefile --console --add-data "csab;csab/" --add-data "josaa;josaa/" tool.py
- Linux环境:
--add-data无需加/*(否则会丢失子目录结构),格式为源文件夹:目标文件夹:
python -m PyInstaller --onefile --add-data 'csab:csab' --add-data 'josaa:josaa' --exclude-module _tkinter tool.py
3. 可选:使用文件夹模式打包
若不需要单文件分发,改用--onedir参数打包(生成包含所有文件的文件夹),资源会直接存放在exe所在目录,路径逻辑更直观:
# Windows示例 pyinstaller --noconfirm --onedir --console --add-data "csab;csab/" --add-data "josaa;josaa/" tool.py
验证方法
在代码中添加打印语句,查看资源实际路径:
print("Resource path:", get_resource_path("csab"))
运行打包后的程序,确认输出路径下存在目标CSV文件。
内容的提问来源于stack exchange,提问作者sauraj
相关产品推荐
相关产品推荐

