新手求教:如何修改PyInstaller的spec文件打包Python脚本为exe?
手把手教你修改PyInstaller的spec文件(适配你的双脚本+JSON场景)
嘿,刚接触PyInstaller的话,spec文件看起来确实有点抽象,我来一步步给你拆解,完全适配你的情况:两个Python脚本(主程序+模块)+一个JSON配置文件。
第一步:先生成基础的spec文件
如果你还没生成spec文件,先打开命令行,切换到你的脚本所在文件夹,运行这条命令:
pyi-makespec main_program.py
这里的main_program.py替换成你的主可执行脚本文件名就行,运行后会生成一个和主脚本同名的.spec文件,比如main_program.spec。
第二步:修改spec文件的核心部分
接下来我们修改这个spec文件,重点处理模块识别和JSON文件打包。我直接给你适配好的代码,你对应替换自己的文件名就行:
# -*- mode: python -*- import os def extra_datas(path): # 这个函数用来打包额外的资源文件(比如你的JSON) datas = [] if os.path.exists(path): # 把文件路径和打包后的路径对应起来 datas.append((path, '.')) return datas # 替换成你的主脚本路径,模块如果被主脚本import了,PyInstaller会自动识别 a = Analysis( ['main_program.py'], # 你的主程序文件名 pathex=['./'], # 脚本所在的文件夹路径,当前目录就写'./' hiddenimports=['your_module'], # 如果模块没被自动识别,就把模块名填这里(不带.py也行) hookspath=None, runtime_hooks=None ) # 添加你的JSON文件到打包资源里 a.datas += extra_datas('config.json') # 替换成你的JSON文件名 pyz = PYZ(a.pure) exe = EXE( pyz, a.scripts, a.binaries, a.zipfiles, a.datas, name='YourExeName', # 生成的exe文件名 debug=False, strip=False, upx=True, # 开启UPX压缩,可选,不想压缩就改成False console=True # 如果是GUI程序,改成False就不会弹出命令行窗口 )
关键部分说明:
- hiddenimports:如果你的主程序已经用
import your_module导入了模块,PyInstaller一般会自动把模块打包进去,这行可以留空;如果打包后运行exe提示找不到模块,再把模块名填进去(比如hiddenimports=['your_module'])。 - extra_datas函数:专门用来处理像JSON这种非代码资源,把它打包到exe里,运行时程序能正常读取到。你只需要把JSON文件名传给这个函数就行。
- EXE部分的name:改成你想要的exe文件名,比如
MyTool.exe。 - console参数:如果你的程序是带命令行输出的,就保留
True;如果是GUI程序(比如用Tkinter、PyQt写的),改成False,运行时就不会弹出黑框了。
第三步:用修改好的spec文件打包
最后在命令行运行这条命令,就会生成exe了:
pyinstaller main_program.spec
打包完成后,exe文件会在当前文件夹的dist目录里。
如果运行exe时遇到找不到JSON的问题,你可以在代码里用sys._MEIPASS来获取打包后的资源路径,比如读取JSON的代码可以改成:
import json import sys import os def get_config_path(): # 判断是打包后的exe还是本地脚本 if hasattr(sys, '_MEIPASS'): return os.path.join(sys._MEIPASS, 'config.json') else: return 'config.json' with open(get_config_path(), 'r') as f: config = json.load(f)
这样不管是本地运行脚本,还是运行打包后的exe,都能正确读取到JSON文件啦!
内容的提问来源于stack exchange,提问作者isrj5




