python利用pyinstaller打包简明教程
pyinstaller简明教程
安装pyinstaller
pip install pyinstaller
是最简单的安装方式,但也常常由于各种原因报错,这就需要我们通过whl文件来下载,但是whl文件安装也有考究,具体参考我之前的教程:Python安装whl文件那些坑,下载whl一般可以在whl文件仓库中找到,如果找不到就去第三方库的官网下载,我个人比较倾向于第二种。
这是我最后一次阐述pip install的问题,后续的教程都不再赘述
pyinstaller基本用法
假如我们要打包一个demo.py文件,基本过程是:
打开cmd,并切换到demo.py文件所在的目录,注意路径中不要有中文
执行命令:pyinstaller demo.py
在当前的目录下,将会生成两个文件夹:build和dist。dist里面就是所有可执行文件,点击demo.exe就能运行了。
pyinstaller指令的常见可选参数:
可选参数 | 格式举例 | 功能说明 |
---|---|---|
-F |
pyinstaller -F demo.py |
只在dist中生产一个demo.exe文件。 |
-D |
pyinstaller -D demo.py |
默认选项,除了demo.exe外,还会在在dist中生成很多依赖文件,推荐使用。 |
-c |
pyinstaller -c demo.py |
默认选项,只对windows有效,使用控制台,就像编译运行C程序后的黑色弹窗。 |
-w |
pyinstaller -w demo.py |
只对windows有效,不使用控制台。 |
-p |
pyinstaller -p E:\python\Lib\site-packages demo.py |
设置导入路径,一般用不到。 |
-i |
pyinstaller -i D:\file.icon demo.py |
将file.icon设置为exe文件的图标,推荐一个icon网站:icon |
-n |
pyinstaller -n 我的gui demo.py |
exe的命名为什么 |
上面的可选参数可以组合使用,比如
pyinstaller -F -i D:\file.icon demo.py
。
能够from xxx import yyy
就尽量不要import xxx
,这样可以减少打包后的体积。
pyinstaller高阶功法
一般而言,pyinstaller的基本用法已经够用了,但是有特殊需求,比如打包图片资源文件时,就必须用到它的高阶功法了。
首先得了解spec文件,简而言之,spec文件就是一份告诉pyinstaller如何打包的配置文件。
可以通过pyi-makespec demo.py
来生成demo.spec文件。其内容如下:
# -*- 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')
对于上面这个文件,需要注意两点:
除了resources配置是我添加修改之外,其余全是自动生成,这个配置是用来添加资源文件的。
pathex是工程的根目录。
生成并配置好spec文件后,我们可以通过pyinstaller demo.spec
来执行打包任务。
一点经验
pyinstaller打包的exe体积往往都非常巨大,而且打包过程非常耗时,和C/C++编译的exe目测差了几个数量级,所以一般没有这个必要去把一个大的python工程打包成exe可执行文件。我想这也是未来python如果想要成为大型软件开发工程的热门语言所要克服的一个重大缺点吧。
常见问题
1.路径问题
-
多文件打包,不会报错。
-
单文件打包,报错。
为什么会报错?加载&解析到临时目录问题。
1.1 sys.argv
路径的使用:
# BASE_PATH = os.path.dirname(os.path.abspath(__file__)) BASE_PATH = "." BASE_PATH = os.path.dirname(os.path.realpath(sys.argv[0]))
1.2 frozen
官方提供的方法:
import sys if getattr(sys, 'frozen', False): # True print('running in a PyInstaller bundle') else: # False print('running in a normal Python process')
import time import os import sys if getattr(sys, 'frozen', False): # pyinstaller打开 BASE_DIR = os.path.dirname(sys.executable) else: # py文件路径 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) print("----环境使用xxx系统----") with open(os.path.join(BASE_DIR, "account.txt"), mode='r', encoding='utf-8') as f: data = f.read().strip() print(data) time.sleep(5)
2. 模块导入的问题
正常导入,通常是可以正常打包的,注意要把当前目录的__init__.py删除
from utils import card
如果遇到那种动态导入模块的代码时,他是无法找到关联的包。
import time import importlib print("----环境使用xxx系统----") # from utils import card # card.get_number() card = importlib.import_module("utils.card") v1 = card.get_number() print(v1) time.sleep(5)
需要在spec文件中的,Analysis中的隐式导入 hiddenimports 加入 "utils.card"
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)