You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

新手求教:如何修改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

火山引擎 最新活动