Python如何将py文件打包成exe
安装pyinstaller
打开cmd窗口,输入pip install pyinstaller,命令行输出successfully表示成功。
打包PY文件
一、单个py文件
在py文件目录下,打开cmd窗口,输入pyinstall -F XXX.py,执行成功的话,会在当前目录生成一个dist文件夹,XXX.exe文件在此文件夹下。
如果是图形窗口,不想要控制台出现的话,可以pyinstall -F XXX.py --noconsole
安装好pyinstaller后,我们会得到两个辅助工具,pyi-grab_version和pyi-set_version。
1. 使用pyi-grab_version创建版本信息模板文件,首先找到一个有版本信息的XXX.exe工具,在此目录下打开cmd窗口,输入pyi-grab_version XXX.exe,执行成功后,会在此目录下获得一个file_version_info.txt文件,这个就是我们要的文件版本信息模板文件。
2. 有了模板文件后,我们需要修改里面的内容,换成我们自己想要的版本内容,最好用nopad++打开。
3. 在打包时加入版本信息。
方法一、还没有打包成exe的py文件
pyinstaller -F --version--file file_version_info.txt XXX.py
方法二、已经打包好的exe
pyi-set_version file_version_info.txt XXX.exe
二、多个py文件
1、尽量将所有要执行的py文件放在一个大文件夹下(里面允许有多个文件夹)
2、命令行输入pyi-makespec main.py 或者 pyi-makespec -F main.py(main.py为Python程序的入口py文件)。
pyi-makespec main.py --> 打包之后会生成一个目录
pyi-makespec -F main.py --> 打包之后只会生成一个exe
选择一个命令即可。
3、现在文件夹下生成了一个main.spec文件和两个文件夹
4、编辑main.spec文件,找到a = Analysis()
第一个参数,放置需要用到的所有py文件。格式为['aaa.py', 'bbb.py', 'ccc.py']。注意:同级目录下,直接写文件名。如果不在同一个文件下,写完整路径,['aaa.py', 'bbb.py', 'c:\\user\\ccc.py']
a = Analysis(['pin.py'], pathex=['F:\\python_work\\pytest\\pin'], binaries=[], datas=[], hiddenimports=[], hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
第四个参数,datas=[]。如果用到了非py文件需要打包,那么找到datas列表,将非py文件的路径与文件夹名写在元组里。比如,有图片文件的话,可以放在images文件夹中,程序中调用图片文件时,需要用绝对路径,才能打包成功。
例如:
datas = [('C:\\project\\test\\images','images'),('C:\\project\\test\\EventLogs','EventLogs')]
datas:
- 第一个参数是Python中的非py类型文件的路径
- 第二个参数是非py文件保存此资源的文件夹名称,要和路径中的文件夹名称相同。
第五个参数hiddenimports=[]。如果打包之后出现No module name.....可以采用临时解决方案,将缺少的模块放置在这个列表中。hiddenimports=['PyQt5.sip']
5、保存文件,在.spec文件路径下打开命令行,输入pyinstaller -D main.spec 或者 pyinstaller main.spec
如果在第2条中选择了pyi-makespec -F main.py ,那么此处只需要执行pyinstaller main.spec即可
6、生成的exe程序在dist文件夹中,dist文件夹里包含了整个项目所需环境,可在其他电脑中进行使用。
特别注意:如果写了关于pyqt5界面的程序的话,并且PyQt5版本在5.13.1之前的话,在其主函数里面导入PYQT5之前需要加上如下代码,在进行打包
import os if hasattr(sys, 'frozen'): os.environ['PATH'] = sys._MEIPASS + ";" + os.environ['PATH'] from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog from PyQt5 import QtCore, QtGui, QtWidgets
如果PyQt5界面的程序还报了No module的错误的话,可以采用临时解决方案,在spec里面hiddenimports里面放置那个module,如果想要exe运行时不显示cmd,可以在console那里打false。
a = Analysis(['aaa.py'], pathex=[''], binaries=[], datas=[], hiddenimports=['PyQt5.sip'], hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, name='game_2048', debug=False, strip=False, upx=True, runtime_tmpdir=None, console=False )
如果需要为exe加上图标的话,可以在console后面加上icon='',填写绝对路径,另外图标的后缀是ico,试过使用jpg格式的,打包没成功。
exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, [], name='game_2048', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, upx_exclude=[], runtime_tmpdir=None, console=False, icon='F:\\2048game\\resouces\\neko.ico' )
参考链接:http://www.yunweishare.com/?p=726
可能遇到的打包问题
1. 如果写的程序中包含multiprocessing,那么打包后运行Tool,会出现无限开启进程,直到CPU内存被占满,电脑彻底死机。
解决办法:
from multiprocessing import Process, freeze_support freeze_support()
先运行freeze_support(),在开始调进程。
2. 在写程序时有import soundfile,但是打包时报错:ValueError: Package 'soundfile' does not exist or is not a package!
参考链接:https://stackoverflow.com/questions/72370766/valueerror-package-soundfile-does-not-exist-or-is-not-a-package-on-auto-py-t
解决办法是:使用最新版本的 pyinstaller(5.3 版)时,我遇到了同样的错误。我通过降级到版本 4.10 解决了这个问题