PyInstaller 3.5离线zip包安装与Python打包exe实战指南
2026/9/8 8:15:17 网站建设 项目流程

简介:压缩包提供 PyInstaller 3.5 版完整源码与安装内容,面向需要将 Python 程序打包成独立可执行文件的开发者,解决目标机器未安装 Python 时的分发部署问题,也适合离线环境或固定版本构建场景。包内共 1307 个文件,其中 Python 源码 873 个、C 源码 20 个,另有 spec 构建配置、可执行文件、动态库、说明文档、图标与测试数据,压缩包整体仅 3.93MB,结构清晰,同时保留测试样例与多平台构建文件,便于对照实验。已有 2229 人学习下载,适合 PyInstaller 使用者、打包流程定制者以及想研究其内部机制的工程师。资源完整保留了核心启动与解压相关的 C 源码、命令行手册、跨平台构建脚本和 UI 资源,方便离线安装或二次开发;通过阅读这些文件,还能掌握依赖收集、资源嵌入和引导程序生成等关键机制。 我第一次拿到pyinstaller-pyinstaller-v3.5.zip这个压缩包时,说实话是有点懵的。文件名一看就是 GitHub 仓库的自动打包产物,但里面装的是什么、怎么装、装完又能干什么,我当时完全没有概念。后来在多个项目里反复用 PyInstaller 把 Python 脚本变成 Windows 下的 exe,再回头看这个 zip,才明白它其实是很多人接触 Python 打包工具时的第一个入口。尤其是当你在内网环境、离线环境,或者只是想通过源码包手动安装时,这类 zip 就派上用场了。

这篇文章不是官方文档的复述,而是把我自己下载、安装、打包、踩坑的完整过程梳理出来。从 zip 包解压后的目录结构,到命令行安装遇到的 PATH 问题,再到真正打包 exe 时的各种报错和应对方案,尽量一次讲透。无论你是刚接触 PyInstaller 的新手,还是已经打包过几个脚本但总在某些问题上卡住的老手,应该都能从这里找到有用的东西。

1. 拿到 zip 包之后:先分清三种安装方式的差别

pyinstaller-pyinstaller-v3.5.zip这种命名方式,是 GitHub 仓库的 Source code 打包格式。解压后会得到一个完整的源码目录,里面有 PyInstaller 主包、bootloader、setup.py、doc、tests 等。这个 zip 和直接用 pip 安装的 pyinstaller 之间的关系,可以从三个层面来看。

安装方式获取位置适合场景常见问题
pip install pyinstallerPyPI联网环境、快速上手下载慢、超时
GitHub zip 手动安装GitHub 源码包离线内网、想读源码依赖缺失、入口脚本缺失
whl 文件离线安装PyPI Release离线环境、避免源码编译必须匹配 Python 版本和平台

如果你只是想打包自己的脚本,直接 pip 是最省事的选择。但如果你拿到手的就是这个 zip,或者需要在隔离网络里安装,那么手动安装的路径必须搞清楚。接下来我按 zip 场景详细说。

1.1 zip 解压后的结构里藏着什么

解压之后,你会看到这样的目录结构:

pyinstaller-pyinstaller-v3.5/ ├── PyInstaller/ ├── bootloader/ ├── doc/ ├── tests/ ├── setup.py └── ...

bootloader这个目录是 PyInstaller 生成 exe 时最核心的组件。它会根据当前的 Python 版本和操作系统,编译生成一个对应的启动加载器,这个加载器负责在目标机器上将打包好的 Python 程序和依赖释放并运行起来。zip 包里的 bootloader 源码是跨平台的,安装过程中会根据你当前解释器自动选择或编译合适的版本。

这里有一个很容易踩的坑:如果你的电脑同时装了多个版本的 Python,比如 Python 3.6 和 Python 3.8,那么你用哪个 Python 去执行安装脚本,生成的 bootloader 就绑定哪个解释器。如果后面换了另一个 Python 来跑打包命令,常会冒出和 bootloader 相关的报错,或者提示找不到对应平台的动态库。所以安装前先确认好你打算用哪个 Python 环境,后续打包全程都用它。

1.2 离线手动安装的正确打开方式

如果 zip 包里的源码版本所依赖的第三方库(比如 altgraph、pefile 等)没有提前装好,直接跑python setup.py install会暴露各种依赖缺失错误。我更推荐这种打开方式:

unzip pyinstaller-pyinstaller-v3.5.zip cd pyinstaller-pyinstaller-v3.5 pip install .

pip install .而不是python setup.py install,原因很简单:pip 会自动解析setup.py里声明的依赖,把它们安装到当前环境的 site-packages,同时在 Scripts 目录下生成pyinstaller.exe入口文件。如果你坚持用 setup.py 直接安装,依赖可能不完整,后续打包时更容易出现隐性问题。

如果是完全离线的机器,更稳妥的做法是在联网机器上用 pip 先把安装包拉下来:

pip download pyinstaller==3.5

这会下载 PyInstaller 本身以及所有依赖的 whl 文件。把它们一起拷贝到目标机器,然后用:

pip install --no-index --find-links=./pyinstaller_packages pyinstaller

这种方式比用 GitHub zip 更干净,因为 whl 是构建好的产物,不需要在目标机器上编译源码中的扩展模块。

1.3 为什么命令行总提示"不是内部或外部命令"

安装完成之后,最常见的一个问题是在 cmd 里输入pyinstaller,系统直接告诉你找不到这个命令。原因通常不是安装失败,而是 Python 的 Scripts 目录没有加进 PATH 环境变量。

Windows 上 pip 安装的可执行文件默认放在类似这样的路径下:

C:\Users\你的用户名\AppData\Local\Programs\Python\Python3x\Scripts

当然如果你用的是虚拟环境,那就是venv\Scripts。有两个解决办法:一个是修改系统环境变量,把 Scripts 目录加进去;另一个是直接用模块方式调用:

python -m PyInstaller --version

我个人的习惯是先跑这条命令做验证,如果能输出版本号,说明安装本身没问题,剩下的只是调用方式的问题。很多教程直接让你敲pyinstaller,一旦失败就引导你重装,结果绕了一大圈。

2. 打包第一个 exe:先理解 PyInstaller 在背后干了什么

很多人并不清楚执行pyinstaller -F xxx.py之后,工具具体做了哪些事情。理解这几个环节,对你排查各种报错非常有帮助。

PyInstaller 的完整流程可以拆成几步:

  1. 分析入口脚本,找出所有 import 的模块,递归生成依赖树。
  2. 收集这些模块对应的字节码、动态库(比如 .pyd、.dll)和扩展文件。
  3. 根据参数把数据文件、资源文件一并纳入。
  4. 将所有这些打包进一个 CArchive 数据块,并拼上匹配当前操作系统和 Python 版本的 bootloader。
  5. 输出到 dist 目录,生成最终的 exe 文件。

理解了这些,你就会明白为什么很多报错是"打包时找不到模块",而另一些是"运行时找不到文件"——这两类问题的排查方向完全不同。

2.1 最小复现:把 hello.py 变成 exe

先看最经典的场景。随便准备一个hello.py

print("Hello, PyInstaller!")

在命令行进入脚本所在目录,运行:

pyinstaller -F hello.py

等待进度条走完,目录结构会变成:

hello.py build/ dist/ hello.exe hello.spec

打开dist\hello.exe,窗口一闪而过,你甚至看不清输出内容。这时可以在 cmd 里直接运行dist\hello.exe,输出就能停留在终端窗口里。这个小细节很多人第一次都会困惑。

2.2 -F 到底要不要加:单文件模式和目录模式之争

-F表示 onefile,打包完成后只有一个 exe。好处是分发方便,发给别人一个文件就行。坏处是运行时需要先把内部资源解压到临时目录,启动速度会慢一些,而且这种自解压行为容易被杀毒软件标记为可疑操作。

-D是目录模式,也是默认模式,生成一个包含 exe 和一整套依赖文件的文件夹。首次启动速度快,调试也方便——因为程序加载了哪些文件一目了然,出问题更容易定位。

我的建议是:自己测试时用-D,正式分发给非技术用户时再用-F。如果你做的是绿色便携软件,-F确实省心,但前提是目标机器上没有拦截它启动的杀软。

需求推荐参数理由
发给同事临时用-D启动快,报错易定位
发布给终端客户-F只交付一个文件,使用门槛低
内部命令行工具-D便于维护和替换依赖
有 GUI 界面-F -w单文件且不弹出黑色控制台

2.3 资源文件和数据文件并不会自动打包

新手最容易犯的错误:脚本里通过相对路径读取config.json,开发时跑得好好的,打包后却报 FileNotFoundError。原因就是 PyInstaller 默认只收集 Python 模块和动态库,你手动 open 的资源文件不在自动收集范围内。

解决办法是使用--add-data参数。在 Windows 上:

pyinstaller -F --add-data "config.json;." main.py

分号后面表示把 config.json 放到打包后的根目录。Linux 和 macOS 上分隔符要改成冒号。

更稳的方式是在代码里写一个通用的资源路径函数:

import sys import os def resource_path(relative): if hasattr(sys, "_MEIPASS"): return os.path.join(sys._MEIPASS, relative) return os.path.join(os.path.abspath("."), relative)

sys._MEIPASS是 PyInstaller 在 onefile 模式下运行时设置的临时解压目录。加上这个函数后,不管开发环境还是打包后的环境,资源文件路径都能正确对得上。

3. 安装完 pyinstaller 却运行不了:我自己的排查顺序

如果已经到了"装完但一跑就报错"的环节,不要急着卸载重装,按下面的顺序过一遍,能定位到九成的问题。

3.1 先分清是"命令找不到"还是"模块导入失败"

在 cmd 里输入:

pyinstaller --version

如果提示"不是内部或外部命令",先去检查 Scripts 目录是否在 PATH 里,或者直接改用模块方式调用。如果提示No module named 'PyInstaller',说明这个包没有装进你当前正在使用的这个 Python 解释器。

第二种情况在多 Python 共存的环境里特别常见。你明明 pip install 成功了,为什么还是找不到?因为你的pippython可能并不属于同一套环境。在 cmd 里分别看一下:

python --version pip --version

如果两者显示的路径不在同一个 Python 目录下,问题就出在这里。解决办法是用python -m pip install pyinstaller,强制把包安装到当前 python 对应的 site-packages 里。

3.2 安装过程卡住、超时或者提示校验失败

PyPI 的下载速度有时确实不稳定,pip 下载到一半就超时的情况我碰到过不少次。有两个方向可以解决。

一是换 pip 镜像源,在命令行里临时指定:

pip install pyinstaller -i https://pypi.org/simple

二是直接下载 whl 文件离线安装。先在联网机器上用pip download pyinstaller==3.5把文件拉下来,然后拷贝到目标机器,用:

pip install pyinstaller-3.5-py2.py3-none-win_amd64.whl

离线 whl 的好处是安装过程完全可复现,不会因为网络波动反复失败。

3.3 路径带空格、杀软拦截这些隐性因素

这是一个很低级但非常伤脑筋的坑。如果把解压后的 zip 放在一个带空格的目录下,比如D:\My Project\pyinstaller,某些依赖处理环节会出问题。尤其是涉及相对路径读取或者调用子进程时,空格可能会让路径解析出错。因此我建议把 PyInstaller 相关的项目目录统一放在无空格的路径下。

杀毒软件方面,Windows Defender 对刚生成的 exe 有时会临时拦截,表现为双击后没有任何反应。常见做法是把项目目录加入杀软白名单,或者暂时关闭实时防护做一次测试。注意我只是让你用于定位问题,不是鼓励长期关闭防护。

4. 真正打包时高频踩到的报错与对策

安装完成、能跑通第一个 hello.py 之后,真正的挑战才刚开始。以下是我在实际项目里反复遇到的几类问题。

4.1 动态导入让静态分析失效,运行时报缺模块

PyInstaller 是通过静态扫描 import 语句来收集依赖的,像下面这种写法它分析不出来:

mod_name = "utils.str_util" module = __import__(mod_name, fromlist=["*"])

运行时走到这一句,Python 会报 ModuleNotFoundError,但打包阶段完全正常。这就是"打包成功、运行失败"的典型代表。

对策有三种:

  1. --hidden-import显式指定:--hidden-import utils.str_util
  2. 在代码里加一个不会执行但仍能触发静态分析的假导入:
    import utils.str_util # 保留,不删除
  3. 把动态导入改成显式从模块字典加载。

我遇到过一个插件系统,模块名是由配置文件中字符串拼出来的,打包后运行时缺了一堆模块,最后就是用--hidden-import逐个补上的。如果你项目里也有类似的插件机制,建议提前扫描一下代码里所有__import__importlib.import_module的调用。

4.2 RecursionError 和内存不足

当项目依赖的第三方库比较多时,PyInstaller 在分析阶段可能报 RecursionError。这通常是某个库自身递归实现得太深,导致默认递归上限被触发。常见于一些代码生成类的库和部分 ORM。

解决方案是修改 spec 文件。在执行过一次打包后,目录下会生成main.spec。打开它,在文件开头增加:

import sys sys.setrecursionlimit(5000)

然后在 Analysis 部分确认入口脚本配置无误。修改完成后,不要再用pyinstaller main.py,而是执行:

pyinstaller main.spec

这样 spec 里的配置才会生效。同理,如果我需要在打包阶段排除某些用不到的模块,也可以用 spec 里的excludes参数,这比命令行参数更灵活。

4.3 换台机器跑 exe 报错"Failed to load Python DLL"

这个问题多发生在用较新版本 Python 打包,但目标机器上没有安装对应版本的 VC++ 运行库时。Windows 上的 Python 从 3.5 开始依赖 Universal C Runtime,如果你的 exe 要在一台裸系统上运行,建议提前把 VC++ Redistributable 装一遍,或者确认目标机器的系统补丁已经更新到支持该运行库的版本。

遇到这类问题,我会先在目标环境里跑一下python --version,确认基础解释器环境一致,再逐步排查其他依赖。很多时候问题并不在 PyInstaller 本身,而在目标机器的系统环境。

4.4 杀毒误报如何缓解

PyInstaller 打出的 exe 经常被误报,本质上是因为它把 Python 解释器、程序代码和依赖打包成一个可自解压的可执行文件。杀毒软件看到"自我解压并释放文件"的行为模式,加上文件没有官方数字签名,就容易产生告警。

应对思路有几种:

  • 给 exe 做代码签名,签名后误报率会明显下降。
  • 把 onefile 模式改成 onedir 模式,减少"启动时自解压"这个敏感动作。
  • 在内网环境里,把程序目录加入杀软排除项。

需要说明的是,误报不等于真的病毒。如果你的代码来源可靠,那么 PyInstaller 生成的包只是因为行为特征相似被放在了可疑名单里。

5. 还在用 v3.5?不妨看看这些升级判断标准

如果你手里这个pyinstaller-pyinstaller-v3.5.zip来自某个老项目,或者目标环境锁死在老版本 Python 上,那继续用老版本并不是什么问题。但如果你的环境允许升级,我建议认真考虑换个更新的版本。

5.1 v3.5 和当前版本的主要差异

PyInstaller 3.5 对 Python 版本的支持范围很有限,大致对应 Python 2.7 和 3.3 到 3.6 这个区间。如果你现在用的是 Python 3.8 甚至更高,v3.5 很有可能装都装不上,更别提打包。新版 PyInstaller 的 bootloader 机制更成熟,对 Windows 上 DLL 的依赖分析也更全,打包生成的程序在目标机器上的崩溃率明显更低。

如果你的目标环境是 Python 3.10 以上,那就不要折腾这个 zip 了,直接去 PyPI 装新版本即可。zip 源码包只在特定历史条件下才有价值。

5.2 什么情况下建议留在老版本

一种情况是你的旧项目虚拟环境里跑的还是 Python 2.7 或 Python 3.5,为了保持打包行为一致,不想引入新版本带来的潜在变化。另一种是长期断网的内网环境,手里只有这个 zip 包,那手动安装的链路就要十分熟练。

我的建议很明确:新项目一律用新版本;老项目如果打包后能正常运行,就别动;手里只有 zip 包且不能联网时,用pip install .方式装,不要直接python setup.py install

最后说一个我自己的操作习惯:每次拿到 PyInstaller 的 zip 包,我都会先在项目根目录建一个临时文件夹专门存放 build 和中间产物,所有输出都指向那里。这样就算打包出问题,也不会污染原项目结构。毕竟打包这件事,脏活累活都让机器去干,自己的项目目录保持干净,后面维护起来才不闹心。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询