将python程序打包成exe
打包成exe需要安装第三方库:
pip install pyinstaller
安装完成,cmd中输入pyinstaller回车查看是否安装成功;
注意事项
该库支持mac,windows的,需要注意的是使用mac打完的包只能在mac上运行,windows打完的包只能在windows运行
快速入门
第一个程序打包
demo8.py
import time
print('我是exe文件按哦')
te=input('请输入内容')
print(te)
time.sleep(3)
在该py文件的目录下使用cmd输入:
pyinstaller -D demo8.py
开始执行打包,打包完成后目录会生成build,dist,demo8.spec文件
- build是指打包过程中的临时文件,这个可以删除不影响
- dist是打包完成的项目目录, 进入后可以看到打包完成的demo8.exe文件,注意这里的文件都是不能删除的
- demo8.spec文件:这个是打包生成后的配置文件,如果打包过程中一些动态包,或者其他资源没有加入进来我们可以配置这个文件,使用这个文件进行打包
多文件打包
命令:pyinstaller -D demo8.py -n demo
其中-n的意思是打包后的exe文件名叫什么
-D打包后生成多个文件
上述快速入门使用的就是
单文件打包
命令:pyinstaller -F demo8.py -n demo
命令:pyinstaller -Fw demo8.py -n demo其中的-w就是设置执行后不展示cmd的黑窗口;
py文件中涉及到其他文件资源文件如何加载使用?
注意:如果是多文件打包,不会报错故不用处理,单文件打包会出现执行找不到资源文件问题,如下方代码
demo8.py
import time
with open('./xuxiriji.md','r',encoding='utf-8') as rf:
ss=rf.read()
print(ss)
print('我是exe文件按哦')
te=input('请输入内容')
print(te)
time.sleep(3)
执行多文件打包运行:打完包后执行发现报错了,说找不到./xuxiriji.md文件,要将该文件和demo8.py文件放在一起即可;
执行单文件打包运行:如果写的相对路径还好,建议写成:
mm=os.path.dirname(os.path.realpath(sys.argv[0]))# 文件存放的目录
sd=os.getcwd()# 文件存放的目录
这样我们的目录就能保证文件可以找得到,将第三方资源文件放在和exe文件相同地方即可;有效的解决文件找不到的问题:
不能使用下方这种错误的方式
import os
import sys
ss=os.path.realpath(sys.path[0])# 获取的是项目执行目录
base=os.path.dirname(os.path.abspath(__file__))# 获取的是项目执行目录
这个获取的项目执行目录!
官网的实例
在官网也提供了解决该场景的问题
演示代码
import os
import sys
if getattr(sys,'frozen',False):
Base=os.path.dirname(sys.executable) # 文件执行时的路径
else:
Base=os.path.dirname(os.path.abspath(__file__))# 文件所在的路径
动态加载第三方包
演示代码
demo8.py
import time
import importlib
print('dddddd')
card=importlib.import_module('headers_from.dd')
print(card.mm)
time.sleep(5)
我们再使用刚才的命令打包执行,结果会发现报错,说第五行找不到该包
Failed to execute script 'demo8' due to unhandled exception!
,所以解决此问题我们可以修改打包的配置文件
也就是demo8.spec文件
打开这个文件
在这个字段中增加要添加的第三方库:hiddenimports
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['demo8.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[
"headers_from.dd",
],
hookspath=[],
hooksconfig={},
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)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='demo8',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
再次打包使用的命令pyinstall demo8.spec回车执行打包啦,注意此时就不需要加-D或者-F了;
生成出来的icon设置,-i指定图标目录即可
其他命令详见pyinstaller的官方文档
如果想让其他资源(图片,视频,文档等)也打包在exe中可以设置资源,但这也就会造成exe很大
# -*- mode: python -*-
block_cipher = None
resources = (("inspurer.db", "."), ("dlib_face_recognition_resnet_model_v1.dat", "."),
("shape_predictor_68_face_landmarks.dat", "."), ("close_logcat.png", ".")
, ("open_logcat.png", "."), ("finish_register.png", "."), ("new_register.png", ".")
, ("start_punchcard.png", "."), ("end_puncard.png", "."), ("index.png", "."))
a = Analysis(['workAttendanceSystem.py'],
pathex=['C:\\Users\\lenovo\\Desktop\\test\\python'],
binaries=[],
datas=resources,
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)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='workAttendanceSystem',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='workAttendanceSystem')
上面还有个变量block_cipher,主要是防止exe被反编译。
可以设置
block_cipher = pyi_crypto.PyiBlockCipher(key='123456789')
加密的详细查看
Python 中如何安全地进行编译和反编译? (qq.com)