PyInstaller打包Python脚本为.exe后无法读取txt文件求助
PyInstaller打包exe后FileNotFoundError问题解决
问题描述
使用PyInstaller将Python脚本转换为可执行文件(.exe)时,程序尝试读取工作目录中存在的searchdata.txt文本文件时触发FileNotFoundError。运行原.py文件一切正常,但转换为.exe后报错。
相关代码片段
import os from docx import Document from docx2pdf import convert doct = 'PDF.docx' docn = 'Reporte de búsqueda.docx' data_dir_path = os.path.dirname(os.path.abspath(__file__)) data_relative_path = "searchdata.txt" data_full_path = os.path.join(data_dir_path, data_relative_path) ubicaciondocx = os.path.join(data_dir_path, docn) # ... (其余代码) doc.save(ubicaciondocx) pdf_name = docn.replace('.docx', '.pdf') convert(ubicaciondocx, pdf_name) os.startfile(pdf_name)
错误信息
FileNotFoundError: #Comment: #Expected result: C:/GENSET-POWER-TABLE/Genset-Power-Table/searchdata.txt #Result: C:/Users/JUSanche/AppData/Local/Temp/_MEI2642/searchdata.txt
打包命令
pyinstaller --onefile --noconsole modificar_doc.py
已尝试方法
os.path.dirname(os.path.abspath(__file__))os.getcwd()os.path.realpath()
以上方法在运行.py文件时正常,但打包为.exe后失效。
疑问与解答
1. 为什么.exe查找文件的目录与.py文件不同?
当使用--onefile参数打包时,PyInstaller会将所有依赖和脚本打包成单个exe文件。运行exe时,它会自动将内容解压到系统临时目录(如C:/Users/xxx/AppData/Local/Temp/_MEIxxxx),然后在该临时目录中执行代码。此时__file__指向的是临时目录中的脚本文件,而非原exe所在的工作目录,导致路径匹配错误。
2. 如何确保.exe能找到searchdata.txt的正确文件路径?
需要区分运行脚本和运行exe两种场景,获取正确的基础路径:
import os import sys def get_resource_path(relative_path): try: # 运行打包后的exe时,获取exe所在目录 base_path = os.path.dirname(sys.executable) except NameError: # 运行.py脚本时,获取脚本所在目录 base_path = os.path.dirname(os.path.abspath(__file__)) return os.path.join(base_path, relative_path) # 替换原路径获取逻辑 data_full_path = get_resource_path("searchdata.txt") ubicaciondocx = get_resource_path(docn)
使用这个函数获取文件路径,无论运行脚本还是exe,都能指向正确的文件位置(需确保searchdata.txt和docx文件与exe放在同一目录)。
3. 是否可以将所需的文本和docx文件与.exe捆绑在一起?
可以,使用PyInstaller的--add-data参数将文件打包进exe,运行时会自动解压到临时目录:
打包命令调整:
pyinstaller --onefile --noconsole --add-data "searchdata.txt;." --add-data "Reporte de búsqueda.docx;." modificar_doc.py
注:Windows系统用分号
;分隔路径,Linux/macOS用冒号:。.;表示将文件打包后解压到与exe执行时的临时目录同级位置。
此时仍然使用上面的get_resource_path函数获取文件路径即可,因为函数会自动定位到临时目录中的文件。如果不需要捆绑,只需将文件与exe放在同一目录,用上述函数也能正常读取。
内容的提问来源于stack exchange,提问作者user23450334
相关产品推荐
相关产品推荐

