【pyinstaller 一步步学会打包教程 】

2023-09-21 13:57:39

基础语法

此处参考官网说明:

pyinstaller [options] script [script …] | specfile

所以最简单的用法如下,即可打包

pyinstaller myscript.py

这个操作即可完成打包,会执行如下操作:

  • Writes myscript.spec in the same folder as the script.

  • Creates a folder build in the same folder as the script if it does
    not exist.

  • Writes some log files and working files in the build folder.

  • Creates a folder dist in the same folder as the script if it does not
    exist.

  • Writes the myscript executable folder in the dist folder.
    一句话总结下就是会跟脚本同一个目录下生成 myscript.spec ,build 目录 dist目录
    其中可执行程序就在dist目录里

一般情况,我们只需要打包主python脚本,如果你在pyinstaller后面包含了多个脚本,那么这些脚本都会包含在输出文件里

另外生成的myscript.spec 也可以用来生成可执行程序

pyinstaller myscript.spec

参数

此处介绍几个常用的,更多的还是请查看官网

必选的参数

脚本或者spec文件

可选的参数:

  • –distpath DIR 指定的app的输出路径,默认情况下是dist目录
  • -D 打包生成一个文件夹
  • -F 打包只生成一个可执行文件 ,这种所有文件都在可执行程序里,打开程序时需要解压缩,速度很慢
  • -p DIR import的时候的搜索路径
  • –hidden-import 同上也是搜索路径,但是最后的输出是不可见的,也就是不会把搜索的脚本输出到可执行文件里

打包详细步骤

首先说明一下我的代码目录,这是用来打包智能翻译的,所以resource中还包括了语料文件和模型文件

src 所有源码的路径
—main.py frozendir.py 以及其他目录文件
resource
—dataset 这是存放语料的路径
—modle_save 模型和词库存放路径

打包多文件

找到主入口脚本以main.py举例,直接

 pyinstaller main.py

pyinstaller会寻找所有main的依赖文件和依赖文件的依赖文件,不论引用了多少个文件,我们只需要简单的打包主文件即可
但是要注意一点,操作的时候发现,如果打包的时候,导入的包的路径,在你打包路径的上一层,比如main.py在src下,而其他文件引入代码是通过from src. xxx import xxx,这时候必须手动添加上这层路径,此时使用 --hidden-import 引入,如下:

–hidden-import=src --paths="E:\code\seq2seq”

当然不引入,启动也一定会失败,报 类似 no moudule named XXX的错误

打包的资源路径问题

打包的时候最头痛的是路径问题,比如程序里需要引用的图片和输入文本文件等,这些文件在我们用ide执行脚本的时候,路径是相对的或者绝对的,无论怎么写都没问题,但是到了打包的程序包里,会有如下问题:
用-F打包成一个文件,所有的资源会被解压缩到一个临时文件里,根本不知道路径是什么
打包的时候用相对路径,但是脚本执行的时候获取的路径是会根据运行脚本的位置在变化,无法锁死路径。
当然官网也给出了解决方案:

  1. frozen 路径

首先在源码的最外层比如我们此处是src,写一个脚本,用于frozen 路径,获取程序执行时的绝对路径

def get_base_dir():
    if getattr(sys, 'frozen', False):
        base_dir = os.path.dirname(os.path.abspath(sys.executable))
    elif __file__:
        base_dir = os.path.dirname(os.path.abspath(__file__))

    return base_dir

这样无论你如何执行,路径都不会再动了

  1. 其他文件配置的路径都基于此
raw_file_path = os.path.join(base_dir, r".\resource\dataset\cmn.txt")
raw_zip_path = os.path.join(base_dir, r".\resource\dataset\cmn-eng.zip")
model_save_path = os.path.join(base_dir, r'.\resource\model_save\ai_net.pkl')

src_vocab_save_path = os.path.join(base_dir, r'.\resource\model_save\src_vocabulary.pkl')
tgt_vocab_save_path = os.path.join(base_dir, r'.\resource\model_save\tgt_vocabulary.pkl')

这样路径就能被固定下来了,例如这里resource的目录是、在可执行程序里的同级目录下的resource目录下,当然resource在打包的时候也需要配合打包到这个目录,下面是怎么配合打包resource目录。

  1. 打包的时候,需要指定resource的路径打包到可执行程序的同级目录下
 pyinstaller.exe  main.py --distpath="..\exe"  --add-data="E:\work\code\seq2seqattention\resource\dataset\*;.\resource\dataset\."  --add-data="E:\work\code\seq2seqattention\resource\model_save\*;.\resource\model_save"

4.最后一点就是注意资源文件如果包含多层目录,多层的打包方式,可以详细看下上面的例子

实操的时候发现pyinstaller 打包的时候,如包含多层就必须一对一都写入,否则打出来的路径会缺失
比如resource下面包含了dataset和model_save,必须一一对应的打包,否则很可能就缺失了一层

5.所有都写完之后,可以现在cmd活着powershell等上执行以下,看是否报错。
如果直接点击打开,很可能闪退,什么都看不到

此时如果是打包到一个目录的方式,就可以在dist目录(未指定打包到其他目录的话)下看到main.exe也可以看到resource目录了
下面是我完成打包一个机器翻译的源码的过程:

 pyinstaller.exe  main.py --distpath="..\exe"  --add-data="E:\work\code\seq2seqattention\resource\dataset\*;.\resource\dataset\."  --add-data="E:\work\code\seq2seqattention\resource\model_save\*;.\resource\model_save"
更多推荐

Android Media3 ExoPlayer 开启缓存功能

ExoPlayer开启播放缓存功能,在下次加载已经播放过的网络资源的时候,可以直接从本地缓存加载,实现为用户节省流量和提升加载效率的作用。方法一:采用ExoPlayer缓存策略第1步:实现Exoplayer参考Exoplayer官网Releasenotes:对应关系:2.19.0(2023-07-05)--Androi

黑马JVM总结(十一)

(1)垃圾回收概述前面我们学了堆,里面有一个垃圾回收的机制(2)判断垃圾_引用计数指只要有一个对象被其他变量所引用,我们就让这个对象的计数加1,有个一变量不在引用,让它的计数减一,当这个对象的计数变为0的时候,说明没有变量引用它了,那么他就可以作为一个垃圾进行一个回收,但是引用计数存在一个弊端:存在循环引用问题:a对象

Pytorch实现MNIST字符识别

1.下载mnist.pkl.gz网址:http://www.iro.umontreal.ca/~lisa/deep/data/mnist/mnist.pkl.gz数据集文件夹路径是data2/mnist/mnist.pkl.gz2.读取数据frompathlibimportPathimportmatplotlib.py

设计模式:状态模式

目录组件代码示例源码中使用优缺点总结状态模式(StatePattern)是一种行为型设计模式,用于解决对象在不同状态下的行为变化问题。状态模式允许对象在内部状态发生改变时改变其行为,使得对象的行为可以根据状态的改变而灵活变化。在状态模式中,对象的行为会根据其内部状态的改变而变化,但对外部来说,对象的接口保持一致。状态模

设计模式之十:状态模式

状态模式通过改变对象内部的状态来帮助对象控制自己的行为。这是一张状态图,其中每个圆圈都是一个状态。最简单,第一反应的实现就是使用一个变量来控制状态值,并在方法内书写条件代码来处理不同情况。packageheadfirst.designpatterns.state.gumball;publicclassGumballMa

9、Spring之推断构造方法源码解析

推断构造方法流程图:Spring推断构造方法底层执行流程|ProcessOn免费在线作图,在线流程图,在线思维导图AutowiredAnnotationBeanPostProcessor中推断构造方法不同情况思维脑图:Spring中的一个bean,需要实例化得到一个对象,而实例化就需要用到构造方法。一般情况下,一个类只

【shell学习】企业运维工作中常用的shell脚本

本站以分享各种运维经验和运维所需要的技能为主《python零基础入门》:python零基础入门学习《python运维脚本》:python运维脚本实践《shell》:shell学习《terraform》持续更新中:terraform_Aws学习零基础入门到最佳实战《k8》暂未更新《docker学习》暂未更新《ceph学习

pytorch学习2

分类问题手写数字数据集其中,每个数字图片大小是28x28,矩阵中每个元素的大小为[0,1]区间的灰度值,将二维矩阵拉平(flat)为一维784,数据量不变,这样能忽略上下位置相关性,甚至左右位置相关性也可忽略,再插入一个维度变为[1,784]线性模型能解决吗一个简单的线性模型为:y=w*x+b但对于手写数字来说,用一个

城中村现代化治理,筑牢基层安全底座

7月21日,李强主持召开常务会议指出,在超大特大城市积极稳步实施城中村改造是改善民生、扩大内需、推动城市高质量发展的一项重要举措。基层(村社)治理是作为社会治理的一个基本单元,是城市治理的一个最后一公里,社会治理的重点在基层,难点也在基层。如何深化数字技术融合创新,推进共建共治共享基层治理全面提速,赋能区域数字经济高质

Linux安装包 | Git使用 | NFC搭建

dpgt使用当谈到基于Debian的操作系统中的软件包管理工具时,dpkg是一个重要的工具。它是Debian系统中用于安装、升级、配置和卸载软件包的命令行工具。以下是对dpkg的详细介绍:软件包管理:dpkg可以管理系统中的软件包。它可以安装单个或多个软件包,并处理软件包之间的依赖关系。通过dpkg-i命令,可以安装软

固定资产管理系统都有哪些功能呢

固定资产管理系统作为企业资产管理的重要工具,具有提高效率、降低成本、保证资产合理使用的多种功能。以下是一些典型的功能:资产登记和信息管理:系统可以自动记录公司的固定信息,包括资产名称、型号、购买日期、原始价值、折旧方法、折旧年限等。同时,系统还支持自动更新和查看资产信息。资产申请和偿还:员工可以通过平台申请或偿还资产,

热文推荐