Python打包原理及示例

1. 简介

1.1. 打包原理

Python代码的基本运行过程:

  1. Python.exe调用XX.py(源码),解释并运行。
  2. Python.exe调用XX.pyc(字节码),解释并运行。
  3. Python.exe调用XX.pyd(机器码),调用运行。
  4. 如果有依赖的库,根据上面三种情况调用运行。

1.1.1. 方法一

分析脚本文件,递归找到所有依赖的模块。如果依赖模块有.pyd文件,即将其复制到disk目录。如果没有.pyd文件,则生成.pyc文件拷贝到disk目录,并压缩为.zip保存。制作一个exe,导入PythonXX.dll(解析器库),并添加exe运行需要的相关运行时库。这就构成了一个不用安装Python的运行包。
如果想生成一个exe,则利用PE结构,将整个包加载内存中,再来运行。

1.1.2. 方法二

.pyd是机器码文件。将.py转换成.pyd的机器码,有两种方式。一种是直接通过虚拟机生成机器码,这种方式,没有做代码优化,性能和虚拟机调用.pyc文件差不多。另一种方式,是将.py转换成而现C代码,C代码是最常见的可以直接编译生成机器码的语言。这样,可能利用C编译器本身的优化功能,可以大幅提高性能。

2. PyInstaller

PyInstaller就是基于方法一进行实现和优化的。

2.1. 安装

PyInstaller支持Win7及之后的操作系统。PyInstaller的运行需要PyWin32的Python扩展来支持。
pip install PyWin32
pip install PyInstaller

2.2. 用法

pyinstaller [options] script [script …] | specfile

-h显示帮助信息
-v显示进度信息
-y不显示确认信息
–clean清除缓存和临时文件
-D产生文件夹存放执行文件等,默认此设置
-F产生一个可执行文件
-n NMAENAME指定生成的exe名,默认第一个脚本名
-w不显示命令行窗口
–hidden-import MODULENAME有些库无法识别(如直接调用.py文件的方式),则需要指定,可以指定多次
–add-data SRC;DEST复制文本文件至指定目录
–add-binary SRC;DEST复制二进制文件到指定目录
–exclude-module EXCLUDES排除指定包或模块
–key KEY利用KEY作为密钥加密字节码
-i <file.ico or file.exe>exe的图标
–version-file FILE版本信息

2.2.1. 优化代码

 # run with basic optimizations
 python -O -m PyInstaller myscript.py
# also discard docstrings
python -OO -m PyInstaller myscript.py

2.2.2. 示例

PyInstaller只需要指定最先执行的脚本文件即可。

  1. 打包成独立exe,使用当前目录下的test.ico,生成Spy.exe

PyInstaller -F -i test.ico -n Spy.exe test.py

  1. 打包到文件夹,不显式控制台窗口

PyInstaller -D -w test.py

  1. 打包到文件夹,添加配置文件flash.ini到当前目录,添加FTL.Dll到DLL目录。

PyInstaller -D --add-data flash.ini;. --add-binary FTL.DLL;DLL test.py

  1. 打包成独立exe,配置版本信息(版本信息参考pyi-grab_version)

PyInstaller -F --version-file ver.txt test.py

  1. 打包至文件夹,添加xlwt库,排除numpy库。

PyInstaller --hidden-import xlwt --exclude-module numpy test.py

  1. 优化打包,注意大小写

python -O -m PyInstaller test.py

3. Nuitka

Nuitka打包的原理基于方法二。Nuitka是一个Python编写的Python解释器,所以Nuitka可以作为Python的扩展库使用。Nuitka会将所有没有生成pyd的模块的.py代码转换成C代码,然后调用gcc/MSVC编译成.pyd(windows DLL)。Nuitka转换的C代码使用了C11,所以C编译器尽量用最新的。

3.1. 安装C编译器

下载MingW的64位和32位,解压到C盘,目录安装如下。
C:\MinGW64\mingw64\bin\gcc.exe
C:\MinGW64\mingw32\bin\gcc.exe
根据打包用的Python版本在环境变量中添加:
CC=C:\MinGW64\mingwXX\bin\gcc.exe

3.2. 安装Nuitka

pip install nuitka

3.3. 用法

–module将指定.py文件编译成.pyd文件
–standalone产生文件夹存放执行文件等
–windows-icon=ICON_PATH给exe添加图标
–windows-disable-console不显示控制台窗口
–recurse-all编译成独立exe

3.4. 示例

  1. 默认只编译指定文件为exe

nuitka --mingw64 test.py

  1. 打包到文件夹

nuitka --mingw64 --standalone test.py

  1. 打包成一个exe

nuitka --mingw64 --recurse-all test.py

  1. 添加图标,并不显示控制台

nuitka --mingw64 --windows-icon=a.ico --windows-disable-console test.py

4. 减小打包大小

打包过大的原因是打包工具不能准确地识别所导入的库,导致收集了很多不需要的库。

4.1. 显式指明模块

imprt XX,隐式相对导入模块,打包工具会收集整个XX模块,导致打包可能收集到错误的模块。应该显式相对导入,即from YY import XX则只会收集YY库中XX模块。Python3.X中已经不推荐使用隐式相对导入。

4.2. 排除无关库

显式指明了导入的模块,打包工具还是有可能将扩展库中的其他没有用到的库也打包进来了。如果发现某些库是不需要的。PyInstaller可以通过–exclude-module EXCLUDES排除相关库。

4.3. 最少安装环境

有些无关库可以人工识别,但是有时复杂调用,人工识别较复杂。此时可以使用只安装使用的库,无关库不安装。这样打包工具就只会打包使用到的库。

4.3.1. 虚拟机环境

可以在VMWare等虚拟机上安装Python,然后安装打包需要的相关库,完成打包。

4.3.2. 虚拟环境

Python扩展库pipenv可以建立一个虚拟的Python环境,然后安装相关库,进行打包。

# 安装pipenv
pip install pipenv
# 建立虚拟环境
pipenv install
# 进入虚拟环境
pipenv shell
# 安装相关模块
pip install XXX
# 开始打包
pyinstaller ......

5. 注意

  1. 路径为英文,最好没有空格。
  2. .py文件使用utf-8编码。
  3. 使用显式导入,即from XX import YY,可以提高PyInstaller依赖库识别,降低打包大小。
  4. 有一些库有资源,PyInstaller不能使用的识别,需要手动将库拷贝到exe所在目录。如:pyecharts库,jieba库等,然后可以删除库中代码,只保留资源即可。
  5. Nuitka功能相比PyInstaller还有不足,也存在一些Bug。通常情况下使用PyInstaller打包,追求性能使用Nuitka打包。
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值