Python程序终端运行正常,PyInstaller打包成EXE后找不到模板文件
问题根源
报错是两个原因叠加导致的:
- PyInstaller 打包后的exe运行时,会将程序资源解压到系统临时目录的随机文件夹下,
__file__此时指向的是临时目录内的脚本路径,和开发时的项目路径完全不一致 - 你没有将
FileRes模板目录打包进exe文件中,运行时自然找不到对应的模板文件
修复步骤
1. 替换路径获取逻辑
兼容开发环境和打包后运行环境,优先读取PyInstaller设置的sys._MEIPASS路径:
首先导入sys模块,然后替换原来的BASE_DIR和template_path定义:
import sys from pathlib import Path import os # 提取为公用方法,也可以直接写在业务代码里 def get_template_path(): # 判断是否是PyInstaller打包后的运行环境 if getattr(sys, 'frozen', False): # 打包后的环境,取临时解压的根目录 base_path = Path(sys._MEIPASS) else: # 开发环境,取原脚本的上级目录 base_path = Path(__file__).resolve().parent.parent return os.path.join(base_path, 'FileRes')
在你的createBasicStructure方法里调用该方法获取模板路径即可:
template_path = get_template_path()
2. 打包时添加FileRes目录
运行PyInstaller打包命令时,加上--add-data参数把模板目录打包进去,Windows环境下命令示例:
pyinstaller -F your_script.py --add-data "FileRes;FileRes"
参数说明:引号内分号前面是你本地开发时FileRes目录的路径,分号后面是打包后解压到临时目录时的文件夹名,这里保持一致用FileRes即可。
3. 可选优化建议
- 所有路径拼接统一用
os.path.join()或者Path对象的/运算符,不要硬写/斜杠,避免跨平台兼容问题,创建目录时可以加exist_ok=True参数省略前置判断,代码更简洁:proj_root = os.path.join(self.location.get(), projName) os.makedirs(os.path.join(proj_root, 'assets/images'), exist_ok=True) - 读写文件用
with上下文管理器,不需要手动调用close(),避免文件资源泄漏,同时指定编码避免乱码:with open(os.path.join(template_path, file), 'r', encoding='utf-8') as f: content = f.read() with open(os.path.join(proj_root, file), 'w', encoding='utf-8') as f: f.write(content) - 不要用裸
except,尽量捕获具体异常类型比如FileNotFoundError、PermissionError,方便后续排查问题。
内容的提问来源于stack exchange,提问作者Dab Hatter
相关产品推荐
相关产品推荐

