Win7/10 64位下PyInstaller打包含子目录Python项目的问题
解决PyInstaller打包后subprocess无限重启及体积/卡顿问题
一、核心问题:subprocess启动main.py时不断重启test.exe
这个问题的根源是单文件打包后脚本路径的认知偏差:
当你用--onefile打包成单个exe时,PyInstaller会把所有文件临时解压到系统临时目录(比如C:\Users\你的用户名\AppData\Local\Temp\_MEIxxxxxx),而你的test.exe运行时,当前工作目录是exe所在的dist文件夹,不是临时目录。
之前你写的subprocess.Popen(['python','main.py',...])会让Python在dist目录找main.py,但这个目录里根本没有!Windows下的shell在找不到指定文件时,会尝试匹配同名的可执行文件(比如test.exe),结果就误启动了test.exe,导致无限循环重启。
解决方法:修改test.py的subprocess调用逻辑
要让程序找到临时目录里的main.py,并调用正确的Python解释器,修改代码如下:
import os import sys import subprocess import time from lib.a import a def main(argv): print('test.py main()') a('test.py') # 获取当前脚本所在的真实路径(PyInstaller解压后的临时目录) script_dir = os.path.dirname(os.path.abspath(__file__)) # 拼接main.py的完整路径 main_py_path = os.path.join(script_dir, 'main.py') # 使用当前运行的Python解释器(避免环境变量版本冲突) proc = subprocess.Popen( [sys.executable, main_py_path, '123', '456'], shell=False, # 关闭shell=True,避免路径解析错误 ) while True: time.sleep(0.5) if __name__ == '__main__': main(sys.argv)
这样修改后,程序会精准找到临时目录里的main.py,用当前运行的Python解释器执行,就不会再重启test.exe了。
二、打包卡顿与体积过大的优化
你用到了pandas和numpy这两个重量级库,打包后体积大是正常的,但可以通过以下方式优化:
1. 解决打包卡顿
- 保留
--noupx参数:UPX对大文件压缩耗时极长,关闭后能大幅提升打包速度,你之前的选择是对的。 - 添加
--clean参数:每次打包清理旧的缓存文件,避免PyInstaller重复处理冗余内容,减少不必要的卡顿。
2. 缩小打包体积
- 使用干净的虚拟环境:创建一个独立的虚拟环境,只安装项目必需的依赖(pandas、numpy、PyInstaller),避免把系统中多余的库打包进去。
- 尝试
--onedir模式:放弃单文件打包,生成一个包含所有依赖的文件夹。这种模式无需解压步骤,体积会比单文件小,运行速度也更快。 - 排除无用依赖:用
--exclude-module参数排除不需要的模块,比如:
注意:排除模块前要确认不会影响程序运行。pyinstaller --noconfirm --onefile --console --noupx --add-data "main.py;." --add-data "lib;lib" --exclude-module tkinter --exclude-module matplotlib test.py
优化后的打包命令
结合上面的建议,最终的打包命令可以写成:
pyinstaller --noconfirm --onefile --console --noupx --add-data "main.py;." --add-data "lib;lib" --hidden-import lib.b --clean test.py
添加--hidden-import lib.b是因为你在main.py的函数内部导入了lib.b,PyInstaller的静态分析可能检测不到这个依赖,提前声明可以避免运行时找不到模块的错误。
内容的提问来源于stack exchange,提问作者Cherrimon Shop
相关产品推荐
相关产品推荐

