
写了个 Python 工具想发给同事用,对方说"我没装 Python"。发 .py 文件过去等于让对方走一遍装环境、装依赖的流程,大概率用不起来。用 PyInstaller 把脚本打成 .exe,对方不用装任何东西,双击就能跑。
三个场景:同事没装环境、不想暴露源码、演示时不想现场装依赖翻车。
01、安装 PyInstaller
bash
pip install pyinstaller
装完确认:pyinstaller --version,输出版本号就行。
02、最基础的打包
先写个测试脚本 hello.py:
python
print("Hello from Python!")
input("按回车退出...")
终端里执行:
bash
pyinstaller -F hello.py
打完后 exe 在 dist\hello.exe。-F 是单文件模式,所有依赖都压在一个 exe 里,发给别人只需要这一个文件。
03、常用参数
|
参数 |
作用 |
示例 |
|
-F |
单文件 exe(便于分发) |
pyinstaller -F app.py |
|
-w |
去掉控制台黑窗口(GUI 程序用) |
pyinstaller -F -w app.py |
|
--icon |
自定义图标(必须是 .ico) |
pyinstaller -F --icon=a.ico app.py |
|
--name |
改 exe 文件名 |
pyinstaller -F --name=压缩器 app.py |
|
--add-data |
附带数据文件 |
pyinstaller -F --add-data "config.ini;." app.py |
两个容易出错的点:
-w 只适合有 GUI 界面的程序(tkinter、PyQt 等)。纯命令行脚本加了 -w,报错信息也看不见了——窗口一闪而过,你什么都不知道。
--add-data 的路径分隔符,Windows 用分号 ;,Linux/Mac 用冒号 :。这个参数经常踩坑,因为写错了不会报明确错误,打包正常但运行时找不到数据文件。
图标只接受 .ico 格式,.png 不行。在线搜"png to ico"有很多转换工具,或者用代码转:pip install pillow 然后 Image.open("a.png").save("a.ico")。
04、打包后的目录结构
CODE
项目目录/
├── hello.py # 源码
├── dist/hello.exe # 成品,发给别人只发这个
├── build/ # 中间产物,可删
└── hello.spec # 打包配置文件,可保留
dist 里的 exe 就是要分发的东西。build 目录是打包过程的临时文件,随时可以删。hello.spec 是打包配置,下次可以直接 pyinstaller hello.spec 复用同样参数。
05、双击闪退怎么排查
双击 exe 黑框一闪就没——程序出错了,但窗口同时关闭。排查三步:
打开 cmd,cd 到 dist 目录,命令行跑 .\hello.exe。报错信息留在终端里,不会消失。
如果用了 -w,去掉 -w 重新打包一次,让报错可见。
代码最后加 input("按回车退出..."),窗口不会自动关。
三种最常见的闪退原因:
缺数据文件。 脚本里读了配置文件或图片,但打包时没用 --add-data 带进去。exe 运行时找不到文件就崩了。
相对路径失效。 你代码里写的 open("data.txt") 用的是相对路径。双击 exe 时的当前目录不一定是 exe 所在目录,相对路径指向了一个不存在的位置。解决办法是用 sys.executable 定位 exe 所在位置:
python
import os, sys
exe_dir = os.path.dirname(sys.executable)
data_path = os.path.join(exe_dir, "data.txt")
依赖漏打。 一些库是动态导入的,PyInstaller 分析不到。比如 pandas 依赖的某些子模块。解决方式是加 --hidden-import=模块名。
06、杀毒软件误报
MOGE NOTES · PART 06
360 和 Windows Defender 拦截 PyInstaller 打出来的 exe 是常态。打包原理是把 Python 解释器和依赖打在一起,特征(壳 + 无数字签名)和某些病毒相似。
处理方式:把 exe 所在文件夹加入杀软的排除列表。Windows Defender 的路径是"设置 → 隐私和安全 → Windows 安全中心 → 病毒和威胁防护 → 管理设置 → 排除项"。如果是在公司内部分发,让 IT 帮忙加白名单。个人用代码签名证书可以彻底解决,但一年几百到几千块,个人项目没必要。
降低误报的小技巧:--name 用正经的英文名而不是 test1、图标正常、别乱加选项——效果有限,但聊胜于无。
07、体积优化
一个 print("hello") 打出 10MB+ 的 exe 是正常的,PyInstaller 把整个 Python 解释器和所有依赖都塞进去了。
按效果排序的优化方案:
第一,用干净的虚拟环境打包。你的全局环境里装了 pandas、numpy、flask 一堆库,PyInstaller 会把它们全打进去。创建一个干净的虚拟环境只装必要的依赖,体积能小很多。
bash
python -m venv venv
venv\Scripts\activate
pip install pillow pyinstaller # 只装需要的
pyinstaller -F app.py
deactivate
第二,不用 -F,用默认的多文件模式。-F 把所有东西压进单个 exe,运行时还要解压到临时目录,更慢更大。默认模式分发时需要整个文件夹,但更小更快。如果是在公司内部用,多文件模式反而更方便。
第三,UPX 压缩。--upx-dir 指定 UPX 路径,能再压 20%-40%。但有风险:可能被杀软更积极地拦截,个别库压完会闪退。先用原 exe 验证功能正常再加 UPX。
08、完整案例:图片批量压缩工具
python
import os
import sys
from PIL import Image
def compress_images(folder, quality=60, max_size=(1920, 1080)):
"""批量压缩文件夹中的图片"""
SUPPORTED = ('.jpg', '.jpeg', '.png', '.bmp', '.webp')
if not folder:
folder = os.path.dirname(sys.executable) if getattr(sys, 'frozen', False) else os.getcwd()
if not os.path.isdir(folder):
print(f"文件夹不存在: {folder}")
return
saved = 0
saved_bytes = 0
for filename in os.listdir(folder):
if not filename.lower().endswith(SUPPORTED):
continue
src = os.path.join(folder, filename)
try:
with Image.open(src) as img:
if img.size[0] > max_size[0] or img.size[1] > max_size[1]:
img.thumbnail(max_size)
out_dir = os.path.join(folder, 'compressed')
os.makedirs(out_dir, exist_ok=True)
dst = os.path.join(out_dir, filename)
if img.mode in ('RGBA', 'P'):
img = img.convert('RGB')
img.save(dst, 'JPEG', quality=quality)
before = os.path.getsize(src)
after = os.path.getsize(dst)
saved += 1
saved_bytes += (before - after)
print(f"压缩: {filename} {before/1024:.0f}KB -> {after/1024:.0f}KB")
except Exception as e:
print(f"跳过 {filename}: {e}")
print(f"\n完成:共压缩 {saved} 张,节省 {saved_bytes/1024/1024:.1f} MB")
print(f"输出目录: {os.path.join(folder, 'compressed')}")
if __name__ == "__main__":
folder = sys.argv[1] if len(sys.argv) > 1 else ""
print("图片批量压缩工具")
compress_images(folder)
input("按回车退出...")
注意 folder 那行——sys.frozen 判断是不是打包后的 exe 环境,是的话用 sys.executable 定位 exe 所在目录,不是的话用 os.getcwd()。这解决了双击 exe 时当前目录不确定的问题。
打包流程:
bash
python -m venv venv
venv\Scripts\activate
pip install pillow pyinstaller
pyinstaller -F --name 图片压缩器 --icon=logo.ico img_compress.py
deactivate
dist\图片压缩器.exe 就是成品。双击前先在命令行跑一次:dist\图片压缩器.exe "D:\test_imgs",确认压缩后图片正常打开、尺寸没问题,再分发给别人。
09、打包成 exe 的几个坑
双击闪退。 先用命令行跑 dist\xxx.exe,八成是缺文件或路径错误。不要一上来就觉得是 PyInstaller 的 bug。
`--add-data` 分隔符写错。 Windows 是分号 ;,Linux/Mac 是冒号 :。这个坑几乎每个新手都踩。
相对路径在 exe 里失效。 exe 运行时的当前目录不一定是 exe 所在目录。用 os.path.dirname(sys.executable) 拼路径。
`--icon` 传 .png 报错。 只接受 .ico。
pandas/matplotlib 打包困难。 依赖树复杂,打包经常失败或体积爆炸。加 --hidden-import 手动指定遗漏模块,或者考虑换轻量实现。
杀软删除 exe。 加白名单或者购买代码签名证书。
每次改代码都要重新打包。 别用旧 exe 测试新功能,也别用旧 exe 分发给别人。
分发前自己当一回纯用户。 把 exe 复制到另一台没装 Python 的电脑上跑一遍全流程,确认没问题再发出去。
以上就是“Python 脚本打包 exe,解决同事没装环境的难题”的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。
扫码二维码 获取免费视频学习资料

- 本文固定链接: http://www.phpxs.com/post/14556/
- 转载请注明:转载必须在正文中标注并保留原文链接
- 扫码: 扫上方二维码获取免费视频资料