尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Python程序打包实战:PyInstaller与Kivy打包EXE和APK全指南

发布时间:2026/9/27 23:47:05

资讯中心
01
ARTICLE

Python程序打包实战:PyInstaller与Kivy打包EXE和APK全指南

Python程序打包实战:PyInstaller与Kivy打包EXE和APK全指南
1. 从脚本到可执行文件为什么打包这件事值得认真对待写过Python的人大概都有过这样的经历本地跑得好好的脚本发给同事或者朋友对方一句“我电脑上没装Python”就把你堵回来了。尤其是做一些小工具、自动化脚本、爬虫可视化界面的时候总不能要求每个使用者都去配一遍环境。这时候把Python程序打包成独立的可执行文件就成了一个绕不开的需求。我自己最早接触打包是在做一个批量处理Excel的小工具时当时用pyinstaller一行命令生成了exe结果文件体积接近300MB启动还要等七八秒被同事吐槽“比打开PS还慢”。后来折腾了好几天才把体积压到30MB以内启动时间也降到了两秒左右。这个过程踩的坑比写代码本身还多。这篇文章要聊的就是把Python程序打包成EXEWindows可执行文件和APKAndroid安装包的完整思路和实操细节。核心工具会围绕PyInstaller和Kivy展开前者负责桌面端打包后者负责把Python程序搬到安卓上。内容会覆盖从环境准备、打包命令、参数调优到体积压缩、图标替换、常见报错排查的全流程。不管你是刚学Python的新手还是已经写过一些项目想分发给别人用的开发者都能从里面找到可以直接抄作业的方案。需要提前说明的是打包这件事没有“一键完美”的银弹。不同的项目结构、不同的第三方库、不同的目标平台都会影响最终结果。所以我会尽量把每个关键决策背后的逻辑讲清楚让你遇到问题时知道往哪个方向排查而不是只会复制粘贴命令。2. 打包前的整体设计与工具选型2.1 桌面端打包为什么PyInstaller是大多数人的第一选择Python打包桌面程序的工具不止一个常见的有PyInstaller、cx_Freeze、Nuitka、py2exe等。我这些年用下来PyInstaller的综合体验是最平衡的。它的核心原理是把Python解释器、你的脚本、以及所有依赖库打包到一个文件夹或者单个文件里运行时先解压到一个临时目录再启动解释器执行代码。这个原理决定了它的优缺点。优点是兼容性好几乎支持所有纯Python库和大部分带C扩展的库缺点是启动时会有一个解压过程所以单文件模式的启动速度会慢一些。Nuitka走的是另一条路它把Python代码编译成C再编译成机器码启动快、体积小但对某些库的支持不够完善编译时间也长。cx_Freeze更轻量但配置起来相对繁琐。所以我的建议是优先用PyInstaller除非你对启动速度或者体积有极端要求再去考虑Nuitka。对于大多数工具类、脚本类项目PyInstaller完全够用。2.2 安卓端打包Kivy加Buildozer的组合逻辑把Python程序跑到安卓上这件事比桌面端复杂得多。安卓的原生开发语言是Java和KotlinPython并不是官方支持的语言。目前主流的方案是Kivy框架配合Buildozer打包工具。Kivy是一个跨平台的Python GUI框架它自己实现了图形渲染不依赖系统原生控件所以能比较方便地移植到安卓和iOS上。Buildozer的作用是自动化整个安卓打包流程它会调用python-for-android这个工具链把Python解释器、Kivy、你的代码一起编译成一个APK。这个过程需要在Linux环境下进行Windows用户通常需要借助WSL或者虚拟机。这一点是很多新手容易忽略的直接在Windows上跑Buildozer大概率会失败。另外要说明的是Kivy打包出来的APK界面风格和原生安卓应用有差异因为它用的是自己的渲染引擎。如果你追求完全原生的体验那Python这条路可能不太适合需要考虑用其他方案。但如果只是做一个功能性的工具Kivy是完全可以胜任的。2.3 打包方案对比与选择建议方案目标平台优点缺点适用场景PyInstallerWindows/Mac/Linux兼容性好、上手快体积大、启动稍慢桌面工具、脚本分发NuitkaWindows/Mac/Linux启动快、体积小编译慢、部分库不支持对性能有要求的项目cx_FreezeWindows/Mac/Linux轻量、配置灵活文档少、易出错简单项目KivyBuildozerAndroid纯Python开发安卓环境配置复杂安卓小工具、演示应用BeeWare多平台原生控件生态不成熟实验性项目这张表是我自己用下来的体感总结不一定绝对准确但能帮你快速定位方向。接下来会分别展开桌面端和安卓端的具体操作。3. 桌面端打包实操PyInstaller从入门到调优3.1 环境准备与基础打包命令先把环境理清楚。我习惯用虚拟环境来打包因为这样能避免把系统里一堆无关的库打进去。用venv或者conda都行关键是只安装项目真正需要的依赖。# 创建虚拟环境 python -m venv pack_env # 激活Windows pack_env\Scripts\activate # 激活Mac/Linux source pack_env/bin/activate # 安装PyInstaller pip install pyinstaller环境准备好之后最基本的打包命令是这样的pyinstaller your_script.py这条命令会在当前目录下生成build和dist两个文件夹。dist里面就是打包结果默认是一个文件夹里面包含exe和一堆依赖文件。如果你想生成单个exe文件加上-F参数pyinstaller -F your_script.py单文件模式看起来更干净但前面说过它启动时会解压所以速度会慢。我的经验是如果项目依赖不多单文件没问题如果依赖了pandas、numpy这种大库建议用文件夹模式启动快很多。3.2 关键参数详解与实战配置PyInstaller的参数不少但常用的就那么几个。我把它们整理成一张表方便你对照使用。参数作用使用建议-F打包成单个文件依赖少时用依赖多时慎用-D打包成文件夹默认模式启动快-w隐藏控制台窗口GUI程序必加命令行工具别加-i指定图标图标必须是.ico格式-n指定生成的文件名避免默认用脚本名--clean清理临时文件每次打包前建议加上--hidden-import手动导入隐藏模块报ModuleNotFoundError时用--add-data添加额外数据文件图片、配置文件等举个实际例子。假设你有一个带GUI的程序main.py用到了requests和Pillow还有一个config.json配置文件图标是app.ico。完整的打包命令可以这样写pyinstaller -F -w -i app.ico -n MyTool --add-data config.json;. --clean main.py注意--add-data的写法Windows下用分号分隔Mac和Linux下用冒号。这个参数很容易写错写错了打包不会报错但运行时找不到文件。3.3 体积压缩与启动速度优化体积和速度是打包的两大痛点。我做过一个统计一个只用了requests的脚本用PyInstaller默认打包单文件大概15MB左右如果用了pandas直接飙到200MB以上。这里面大部分体积是numpy和pandas的二进制文件。压缩体积有几个实用手段。第一用虚拟环境确保没有多余依赖。第二用--exclude-module排除明确不用的模块比如打包GUI程序时可以排除tkinter如果你没用的话。第三用UPX压缩PyInstaller支持调用UPX来压缩二进制文件能再减小20%到30%的体积。# 安装UPX后打包时加上--upx-dir pyinstaller -F --upx-dir/path/to/upx main.py启动速度方面单文件模式慢是硬伤。如果实在需要单文件可以考虑用--runtime-tmpdir指定一个固定的解压目录避免每次启动都重新解压。不过这个做法有风险如果多个实例同时运行可能会冲突。还有一个容易被忽略的点减少顶层导入。如果你的脚本在开头就import pandas那打包后启动时一定会加载pandas。可以把一些导入放到函数内部用到的时候再导入这样能明显加快启动速度。3.4 图标替换与版本信息设置图标替换用-i参数就行但要注意图标必须是.ico格式而且最好包含多个尺寸16x16、32x32、48x48、256x256。网上有很多在线工具可以把png转成ico选一个靠谱的就行。版本信息是很多人不知道的功能。你可以创建一个version.txt文件内容格式如下VSVersionInfo( ffiFixedFileInfo( filevers(1, 0, 0, 0), prodvers(1, 0, 0, 0) ), kids[ StringFileInfo([ StringTable( 040904B0, [StringStruct(CompanyName, Your Company), StringStruct(FileDescription, Your Tool), StringStruct(FileVersion, 1.0.0), StringStruct(ProductName, Your Product)]) ]) ] )然后在打包时加上--version-fileversion.txt。这样生成的exe在属性里就能看到版本信息看起来更正规。4. 安卓端打包实操Kivy与Buildozer完整流程4.1 Kivy环境搭建与最小示例Kivy的安装很简单pip install kivy就行。但要注意Kivy在Windows上的窗口渲染有时候会有问题如果遇到黑屏或者闪退可以尝试安装kivy_deps相关的依赖包。先写一个最小的Kivy程序验证环境是否正常from kivy.app import App from kivy.uix.button import Button from kivy.uix.boxlayout import BoxLayout class MyApp(App): def build(self): layout BoxLayout(orientationvertical) btn Button(text点击我) btn.bind(on_pressself.on_press) layout.add_widget(btn) return layout def on_press(self, instance): instance.text 被点击了 if __name__ __main__: MyApp().run()运行这个脚本如果能看到一个窗口和一个按钮说明Kivy环境没问题。这个程序后面会用来打包成APK。4.2 Buildozer配置与打包流程Buildozer必须在Linux环境下运行。Windows用户可以用WSLMac用户可以用虚拟机或者Docker。我个人的做法是在Ubuntu虚拟机里操作避免污染主力机环境。安装Buildozerpip install buildozer然后在项目目录下初始化配置buildozer init这会生成一个buildozer.spec文件里面是各种配置项。这个文件很关键我挑几个必须改的说明一下。# 应用名称 title MyApp # 包名通常是com.公司名.应用名 package.name myapp package.domain org.test # 入口文件 source.include_exts py,png,jpg,kv,atlas source.main main.py # 版本 version 0.1 # 权限按需添加 android.permissions INTERNET # 最低API级别 android.minapi 21 # 目标API级别 android.api 31 # 架构建议只保留arm64-v8a减小体积 android.archs arm64-v8a配置改好之后执行打包buildozer android debug第一次打包会下载大量依赖包括Android SDK、NDK、python-for-android等可能需要半小时到一小时取决于网络速度。打包成功后APK会生成在bin目录下。4.3 APK签名与安装测试debug版本的APK可以直接安装但如果你想发布或者分享给更多人用就需要签名。签名需要一个keystore文件可以用keytool生成keytool -genkey -v -keystore mykey.keystore -alias myalias -keyalg RSA -keysize 2048 -validity 10000然后在buildozer.spec里配置签名信息android.release_artifact apk android.keystore mykey.keystore android.keystore_passwd yourpassword android.keyalias myalias android.keyalias_passwd yourpassword之后用buildozer android release打包生成的就是签名后的release版本。安装测试的时候把APK传到手机上用文件管理器点击安装就行。如果提示“解析包错误”通常是API级别或者架构不匹配检查一下buildozer.spec里的配置。4.4 安卓打包的常见坑与规避方法安卓打包的坑比桌面端多得多。我列几个最常遇到的。第一个是网络问题。Buildozer第一次运行要下载很多东西如果网络不稳定很容易卡在某个步骤。建议提前配置好镜像源或者手动下载好SDK和NDK放到指定目录。第二个是依赖库兼容性。不是所有Python库都能在安卓上跑。纯Python库一般没问题但带C扩展的库比如numpy、scipy需要python-for-android提供对应的编译配方。如果某个库没有配方打包就会失败。Kivy官方维护了一批常用库的配方但覆盖范围有限。第三个是内存不足。编译过程很吃内存如果虚拟机内存小于4GB可能会在编译numpy时被kill掉。建议给虚拟机分配至少8GB内存。第四个是API级别冲突。有些库要求较高的minapi有些又要求较低的需要根据实际情况调整。我一般从21开始试不行再往上加。5. 常见问题与排查技巧实录5.1 桌面端打包典型报错速查报错信息原因解决方法ModuleNotFoundError隐藏导入未识别加--hidden-import模块名找不到数据文件路径问题用--add-data代码里用sys._MEIPASS启动闪退缺少依赖或报错去掉-w看控制台输出体积过大依赖过多虚拟环境UPX排除模块图标不生效格式不对用多尺寸.ico文件杀毒软件误报PyInstaller特征加白名单或换Nuitka关于数据文件路径这里展开说一下。PyInstaller打包后程序运行时的工作目录会变所以代码里不能直接用相对路径。正确的做法是这样import sys import os def resource_path(relative_path): if hasattr(sys, _MEIPASS): return os.path.join(sys._MEIPASS, relative_path) return os.path.join(os.path.abspath(.), relative_path) # 使用 config_path resource_path(config.json)sys._MEIPASS是PyInstaller运行时创建的临时目录所有--add-data添加的文件都会解压到这里。5.2 安卓端打包失败排查思路安卓打包失败时Buildozer会输出大量日志。关键是找到第一个Error或者FAILED出现的位置。常见的失败点有下载SDK超时、NDK版本不匹配、某个库编译失败、内存不足被kill。我的排查习惯是先看日志最后20行找到具体的错误信息然后去搜这个错误。大部分问题都有人遇到过尤其是Kivy和python-for-android的GitHub issue里能找到不少解决方案。如果实在搞不定某个库可以考虑换一个替代方案。比如numpy在某些情况下编译困难可以试试用纯Python的替代实现或者把计算逻辑放到服务端客户端只做展示。5.3 独家避坑经验分享说几个文档里不会写、但实际很管用的技巧。第一打包前先清理__pycache__和.pyc文件。这些文件有时候会导致打包结果异常尤其是你改过代码但没重新编译的时候。第二用--log-levelDEBUG看详细日志。PyInstaller默认日志比较简略加上这个参数能看到每一步在做什么排查问题很有用。第三单文件模式不要放太多数据文件。每次启动都要解压数据文件越多越慢。如果数据文件超过50MB强烈建议用文件夹模式。第四测试打包结果时换一台没装Python的电脑。在自己的开发机上测试很容易因为环境变量或者已安装的库而“看起来正常”换台干净机器才能暴露真正的问题。第五安卓打包的APK体积普遍偏大。一个最简单的Kivy应用APK也在20MB以上因为里面包含了Python解释器和Kivy的渲染引擎。这是正常现象不用太纠结。6. 打包之外的延伸思考打包这件事表面上是技术操作实际上是对项目结构的一次检验。我打包失败最多次的项目往往是那些依赖混乱、路径写死、没有考虑分发场景的项目。反过来那些结构清晰、依赖明确、路径处理规范的项目打包过程通常很顺利。所以如果你在打包时遇到各种奇怪问题不妨回头看看代码本身。是不是有硬编码的绝对路径是不是导入了用不到的库是不是把配置文件和代码混在一起了把这些理顺打包会轻松很多。另外打包不是终点。如果你要分发给很多人用还需要考虑自动更新、错误上报、使用统计这些事情。这些就不在本文范围内了但值得你在项目规划时提前想一想。最后分享一个我自己的习惯每次打包成功后把buildozer.spec或者PyInstaller的命令行参数保存到一个脚本文件里下次直接运行脚本就行。这样既避免了忘记参数也方便在不同机器上复现。打包环境很容易变有个记录会省很多事。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。