Pyinstaller打包单个bundle时封装额外的资源文件

Pyinstaller简易使用说明:

安装:

pip install pyinstaller

在待打包目录下

新建一个批处理specgen.bat,内容为

pyi-makespec.exe Name.py -F -w –icon=fav.ico

新建一个批处理exegen.bat,内容为

pyinstaller.exe Name.spec

执行specgen.bat生成spec文件(若有需要,对其进行修改)

执行exegen.bat生成可执行文件,结果位于dist目录下

正文:

在编程时往往会引用一些额外文件,如图片,音乐等。

若是用Pyinstaller打包为文件夹,那么这些文件直接复制过去就行。

而在打包为单文件exe时,通常这些文件是不希望用户直接能够看见的,因此有了这篇文档。

一.添加附件的方法。

事实上,官方指南给出了详细的方法,没有例子且有些生涩。我只做具体操作的转述,机理有心情再附上。

概述:

将附件打包至exe非常容易,但是源程序要做必要的修改,这些文件不再能简单使用相对路径。

详解:

Step1:添加basedir在待打包的主程序头部

if getattr(sys, 'frozen', False): # we are running in a |PyInstaller| bundle basedir = sys._MEIPASS else: # we are running in a normal Python environment basedir = os.path.dirname(__file__)

Step2:待打包附件全部添加至某文件夹,如myimages

程序内所有引用均应当这么写:basedir+’路径’

open(basedir+’/myimages/fav.ico’)

Step3:修改打包参数

  1. 生成一个spec文件
在spec文件中添加

extra_tree = Tree(‘./myimages’, prefix = ‘myimages’)
3. 在a.scripts等a.开头文件所在的部分后添加extra_tree
4. 直接用修改的spec打包即可。

例如:

extra_tree = Tree('./myimages', prefix = 'myimages') exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, extra_tree, name='test.exe', debug=False, strip=None, upx=True, console=False , icon='fav.ico')

Enjoy it!

二.运行机理。

在打包为单文件exe时,先分析所需运行文件,然后把这些文件利用Tree函数形成一个文件目录树,运行时将这些文件 释放至C:UsersUSERNAMEAppDataLocal下的一个临时文件夹XXXXX内。程序自身引用此目录的绝对路径来获得所需的文件。此时,对于程序,他所见的目录仍然是exe所存储的目录。

也就是说,程序里的open(‘sample.txt’)打开的是程序所在目录下的sample.txt,而非临时文件夹下的。

extra_tree = Tree('./myimages', prefix = 'myimages')

对照打包函数,pyinstaller对额外资源的打包,实质也是利用Tree函数生成一个文件目录树,也将这些文件压进exe,并释放到临时目录中。

其中:

第一个参数’.images’是待打包的目录地址,将会将该目录下所有文件添加至文件树。

第二个参数prefix = ‘myimages’则意为:这些文件在运行时将被解压至临时文件夹中名为’myimages’的文件夹下。若没有这个参数,则这些文件会被释放到临时文件夹中。

于是乎,basedir的作用就体现了,他是官方文档中给出的获得基础目录的函数,其作用及原理已经注释的很清楚。

附注:

文件树(官方文档中称为Table of Class):类似于python的列表变量。Tree函数将所有文件均添加为’DATA’型数据

其结构为:[(‘解压后地址’, ‘文件地址’, ‘类型参数’)]

例如

[('README', '/my/project/readme', 'DATA')]

Pyinstaller打包单个bundle时封装额外的资源文件》有一个想法

评论已关闭。