Pyinstaller-打包python程序的利器

本文转载自知乎:Pyinstaller-打包python程序的利器

一、环境

OS:Win11 Python Version:3.10.* 编辑器:VS Code

二、打包成为exe的两种工具

PyinstallerNuitka都可以打包python,相对来讲,Pyinstaller文档相对多一些,上手相对容易。而Nuitka上手相对复杂,不光配置复杂,命令参数也复杂,但是通常来看,上手困难的东西更容易玩得好。

使用Nukia打包exe、使用Nsis工具HM VNISEdit打包安装程序、使用Inno Setup Compiler打包安装程序,见https://blog.csdn.net/qq_38830593/article/details/123109079

1、Pyinstaller

✨Pyinstaller可以打包Win、Linux、MacOS下的python程序,在什么环境下打包的就是什么平台的程序。相对来看,Pyinstaller打包的程序体积大、安全性稍差(容易反编译),但是上手相对简单一些。

参考 URL
Documentation: https://pyinstaller.readthedocs.io/
Website: http://www.pyinstaller.org/
Code: https://github.com/pyinstaller/pyinstaller

1.1、安装

Pyinstaller 可以直接通过pip命令安装

pip install pyinstaller

验证安装是否成功,提示版本号即安装成功

pyinstaller -v

若提示 “pyinstaller不是内部或外部命令” 这类错误,则是由于python环境变量没有将pip安装包的位置添加进系统环境变量,添加一下即可❗️ 还有一个容易出现的问题就是:如果手动切换过pip安装包缓存文件夹的位置,尤其是通过设置pip配置文件切换的,会偶发性的出现设置环境变量后依旧无效的现象,这种要不就取消设置,或者重装python。

1.2、打包的两种方式

一般用Pyinstaller打包会同时生成builddist文件夹和.spec文件,dist文件夹里边是我们最终想要的结果。剩下两个文件我们稍后介绍。

1.2.1、打包为单文件

平时我们见到很多便携的单文件程序,假如我们写了一个小脚本,寥寥数行代码,打包成一个文件夹显然不合适,这就可使用Pyinstaller打包成一个exe

# 将 xx.py 打包为 xx.exe
pyinstaller -F xx.py

其实单文件在执行的时候也是需要释放资源文件的,不过是释放在了系统默认的缓存位置,如果是软件稍复杂,那么打开就比较慢,这时候就不适合打包成单文件程序,而是打包为一个文件夹,点开执行

1.2.2、打包为文件夹

# 将 xx.py 打包
pyinstaller xx.py

有时候我们需要在打包的程序中调用一些资源文件,但是pyinstaller并不会自动的帮我们打包进去,每次都得手动复制进去,比较麻烦,其实可以配置pyinstaller让他打包的时候自动复制进去,这时候就需要手动更改.spec文件了。

1.3、打包资源文件夹

细心的小伙伴可能发现,打包的时候,程序同路径下会生成一个同名的.spec文件,这个文件是打包的 “中间文件”,我们可以通过修改这个文件来添加我们需要添加资源的文件。

1.3.1、Spec文件分析

.spec文件中主要包含4部分:AnalysisPYZEXECOLLECT

  • Analysis:主要是分析py文件的依赖信息
  • PYZ:是一个.pyz的压缩包,包含程序运行需要的依赖
  • EXE:是根据上述两项内容而生成的
  • COLLECT:主要是输出信息

这里放一个我之前打包生成的spec文件的Analysis部分截取作为示例:

# -*- mode: python ; coding: utf-8 -*-
a = Analysis(['gui.py'],
             pathex=['D:\\gui'],
             binaries=[],
             datas=[('D:\\gui\\config.ini','.'),('D:\\gui\\清洗规则.xlsx','.')],
             hiddenimports=['pandas'],
             hookspath=[],
             hooksconfig={},
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)

1.3.2、参数详解

想要添加资源文件,重点是修改datas的内容,我这里是修改过的,一般是空的:datas = [] datas里边的元素是以元组的形式来存储的,有这么一个映射关系:

datas = [('源文件路径','目标路径')]

如果有多个,就多放几个元素,内容不限,如果目标路径打包后的根目录,那就写.

修改好之后,运行这条命令即可:

pyinstaller -D xx.spec

程序写好了,但是文件夹形式不方便分发,也显得比较low,那我们就需要打包成安装程序

1.4、去掉命令行窗口

根据之前的命令打包的好的程序,可以运行,但是会带一个命令框,黑乎乎的,对于命令行程序还好,但假如是GUI,那体验就太糟糕了

# 添加 -w 参数可以隐藏命令行窗口
pyinstaller -w xxx.py

1.5、给程序增加图标

程序打包好了,黑框也去掉了,但是程序看起来像是快捷方式丢失一样,很不美观,我们需要给程序增加一个漂亮的面具

# 添加 -i 参数,后加 图标路径
pyinstaller -i x:\xx\xx.ico xx.py

1.6、减小打包文件的体积

Pyinstaller打包会打包进很多和本项目无关的包,只要你环境中安装了,这会导致我们项目的体积非常大,有两种方案来减小打包的体积:

1.6.1、虚拟环境纯净打包

首先通过 venv模块来创建虚拟环境:

# venv 后边跟你想存放虚拟环境的路径即可
python -m venv D:/pyvenv

然后启动这个环境,如果是用的VS CODE,这么设置就好:⬇️

这是从我另一篇博文里截过来的,所以是 python version 3.8.6

Pyinstaller-打包python程序的利器_第1张图片

然后选择:⬇️
Pyinstaller-打包python程序的利器_第2张图片

再次打开终端,显示这样就是设置成功了⬇️

Pyinstaller-打包python程序的利器_第3张图片

然后在这里执行安装命令就好了,如果哪一天不想用这个虚拟环境了,删掉那个文件夹就好了

然后再在这个环境中打包就可以避免打包进来那些乱七八蕉的包,体积会小很多!

一般情况下,可以通过在虚拟环境打包来减小体积,效果也很显著,不过还可以进一步压缩

1.6.2、通过UPX压缩打包

Pyinstaller也支持UPX[下载],使用UPX进一步来压缩生成文件,例如

# 添加 --upx-dir 参数 后跟upx路径
pyinstaller --upx-dir=x:\xxx\upx.exe xx.py

1.7、其他常用参数

-h	       查看该模块的帮助信息
-F	       产生单个的可执行文件
-D	       产生一个目录(包含多个文件)作为可执行程序
-w	       指定程序运行时不显示命令行窗口(仅对 Windows 有效)
-o	       [dir]指定 spec 文件的生成目录。如果没有指定,则默认使用当前目录来生成 spec 文件
–upx-dir      使用upx对文件进行压缩,减小文件体积
–clean	       在构建之前,请清理PyInstaller缓存并删除临时文件。
-a	       不包含 Unicode 字符集支持
-d	       产生 debug 版本的可执行文件
-c	       指定使用命令行窗口运行程序(仅对 Windows 有效)
-p	       [dir]设置 Python 导入模块的路径(和设置 PYTHONPATH 环境变量的作用相似)。
-n	       指定项目(产生的 spec)名字。如果省略该选项,那么第一个脚本的主文件名将作为 spec 的名字

1.8、安全性

打包如此便捷,但是破解是否也是如此简单呢❓

1.8.1、反编译

查阅了一些相关资料后,发现解包还原代码也很简单

先下载pyinstxtractor包,提取生成的exe中的pyz(一般是pyc)文件

# 安装:直接执行下载的 py 文件即可
# 解包 xx.exe
python pyinstxtractor.py xx.exe

执行命令后会生成xx.exe_extracted文件夹,xxx.exe.manifest文件等。再找到一个没有后缀名的文件,就是打包的.py文件对应的pyc

然后再通过[python-uncompyle6](https://link.zhihu.com/?target=https%3A//github.com/rocky/python-uncompyle6)工具,将pyc文件反编成.py文件

# 安装 
pip install uncompyle6
# 反编译 xxx.pyc 文件,输出为 xxx.py 源码文件
uncompyle6 -o xxx.py xxx.pyc

反编译这块我不太懂,网上有很多可以参考的教程,大家可以搜索一下,基本逻辑就是这样参考教程

1.8.2、加密

虽然被如此轻松的解密手段到了,但是Pyinstaller也是支持加密打包的,使用 --key + 密码 参数即可,例如:

pyinstaller --key 666777 xxx.py

不过这个加密也不是很强,对保密性有很强要求的建议使用把需要加密的模块通过C或者C++编写,通过python调用,再打包。

1.9、pyinstaller打包常见错误

utf-8' codec can't decode byte 0xce in position

# 若出现上述错误,则输入以下命令
chcp 65001

这是由于cmd的编码格式导致的。

各种路径错误导致的问题

很多人在拼接路径的时候喜欢使用+来拼接路径字符串,这会导致在打包后出现各种资源无法访问的错误,且不好排查,建议多使用os.path的各种方法来处理路径。


本文转自 https://zhuanlan.zhihu.com/p/470301078,如有侵权,请联系删除。

你可能感兴趣的:(python,python,开发语言)