Python技术迷

将 Python 脚本转换为 .Exe 文件的 3 种方法

日常写 Python 的时候,大家是不是都有这种场景: 脚本写完跑得好好的,结果领导一句“发我一下,我电脑也要跑跑”,你只能尴尬地解释:还得先装 Python、装依赖、配环境、改路径……最后对方一句“算了算了,太麻烦了”,这事就黄了。

所以,把 .py 打包成 .exe,本质上就是一句话:让不会折腾环境的人,也能一键双击运行你的程序。

下面我就按“实用优先”的思路,聊三个把 Python 脚本变成 .exe 的常用办法,难度从低到高,都是我自己踩过坑的那几种。示例都按 Windows 环境来,语言就是 Python。

先准备一个最简单的小脚本,我们后面三个方案都用它打包,方便对比。

# hello.py
import sys
from datetime import datetime

defmain():
    print("Hello, exe world!")
    print("当前时间:", datetime.now())
if len(sys.argv) > 1:
        print("你传入的参数是:", sys.argv[1:])
else:
        print("没有传入参数~")

if __name__ == "__main__":
    main()

假设这个文件就在当前目录:D:\demo\hello.py。

说第一个方案:最常见、也是我最推荐的 —— PyInstaller

这个基本是 Python 打包界的“标配”了,优点是:简单、资料多、支持第三方库比较好。

1)安装 PyInstaller

pip install pyinstaller

建议用虚拟环境,这样打包出来不会乱七八糟把一堆奇怪的东西带进去。

2)最简单的打包命令

在 hello.py 所在目录打开终端(PowerShell / CMD 都行):

pyinstaller hello.py

跑完之后,你会看到多了两个目录:

  • build/:中间产物,基本不用管
  • dist/:真正的成品就在这里,里面会有 hello/ 目录,目录里有 hello.exe 和一堆 dll、pyd、依赖文件

这种默认方式有几个特点:

  • 是“文件夹版”程序:.exe 旁边一大堆文件
  • 控制台程序:双击会弹出黑框框(console 窗口)
  • 体积偏大,但基本“开箱可用”

3)如果你想要一个单文件 .exe

很多人比较在意这一点:能不能就一个 exe 文件发给别人?可以,用这个命令:

pyinstaller -F hello.py

-F(等价于 --onefile)的意思就是打成单文件,生成的文件在:

dist/hello.exe

不过这里有两个现实问题提前跟你说清楚:

  • 单文件启动速度会变慢一点,因为运行时要先在临时目录解压依赖
  • 某些杀毒软件会更“敏感”,误报的概率略高一点

4)做一个“没有黑框”的 GUI 程序

有时候你其实做的是一个图形化程序(比如 Tkinter、PyQt、PySide),不想要黑色控制台窗口。命令加一个 -w 即可(windowed):

pyinstaller -F -w hello.py

注意: 如果你的程序本来就是命令行工具,那就别加 -w,不然你连日志、错误信息都看不到了,出了问题很难排查。

5)常见问题几个点提前说一下

  • 脚本里用到了相对路径读文件,打包后路径会乱 → 打包程序里用 sys._MEIPASS(onefile 模式下的临时目录)或 os.path.dirname(sys.executable) 做基准路径。
  • 第三方库没被打进去(尤其是动态 import 的) → 可以用 --hidden-import 手动指定,或者写一个 .spec 文件微调。
  • 体积太大 → 这是 Python 打包的“通病”,可以试着排除不必要的包、用 --exclude-module,但别指望变得很瘦。

整体来说,如果你只是想“让我这个脚本给同事能跑起来”,PyInstaller 足够用了。

第二个方案:怕命令行麻烦,就用 auto-py-to-exe 图形界面

很多同学一看那么多参数就头大,我一般会推荐他们先玩玩 auto-py-to-exe,本质上它还是用 PyInstaller 打包,只是帮你做了一个 GUI 配置界面。

1)安装工具

pip install auto-py-to-exe

2)启动图形界面

auto-py-to-exe

跑完会自动打开一个浏览器窗口(或独立窗口),大概包含这些配置项:

  • 选择脚本:选你的 hello.py
  • Onefile / Onedir:单文件 or 目录模式,勾选 Onefile 就是 -F
  • Console / Window Based:是否需要控制台(等价于有/没有 -w)
  • Icon:可以选一个 .ico 图标文件
  • Additional Files:给程序加额外文件(比如配置、图片、模板等)
  • Advanced:一些高级选项,对照 PyInstaller 的帮助就能看懂

3)使用体验上有什么不一样?

  • 优点:

    • 不用记命令行参数
    • 所有选项都摆在界面上,一目了然
    • 可以一边点一边看右侧它生成的命令行,顺便学习 PyInstaller 的参数怎么写
  • 缺点:

    • 本质还是 PyInstaller,能解决的问题是同一类
    • 有时候图形界面会因为 Python 环境或者浏览器怪异行为卡住,需要重开

4)适合什么场景?

我一般这样用它:

  • 第一次打包时,用 auto-py-to-exe 先把参数调好
  • 左下角有个地方可以导出配置(或复制生成的 PyInstaller 命令)
  • 后面写到 CI 或打包脚本里,就直接用命令行版 PyInstaller 自动化打包,不用每次点点点

比如你在界面里选好了各种选项,右侧可能出现类似命令:

pyinstaller --noconfirm --onefile --console  \
  --icon "app.ico" \
  --add-data "config.yaml;." \
"hello.py"

以后你就直接拿这条命令用就行,这也是我比较喜欢这个工具的一个原因:它既友好,又不会把你困在图形界面里。

第三个方案:想要更“工程化”一点,可以试试 cx_Freeze

如果你是做桌面应用、甚至要做安装包、版本管理那一类的,或者未来脚本会变成一个正儿八经的小软件,推荐看看 cx_Freeze。它的思路更接近“写一个 setup 脚本,然后构建”。

1)安装 cx_Freeze

pip install cx_Freeze

2)写一个打包脚本 setup.py

在和 hello.py 同级目录新建 setup.py:

# setup.py
from cx_Freeze import setup, Executable

build_options = {
"packages": [],
"excludes": [],
# 可以在这里指定包含的文件,比如配置、图片等
# "include_files": ["config.yaml", "assets/"],
}

base = None# 控制台程序
# 如果是 GUI 程序(比如 Tkinter),可以写 base="Win32GUI"

setup(
    name="HelloExeDemo",
    version="1.0.0",
    description="一个简单的 Python 打包示例",
    options={"build_exe": build_options},
    executables=[Executable("hello.py", base=base, target_name="hello.exe")]
)

这里几个点说明一下:

  • name / version / description:就和普通 Python 包差不多
  • Executable("hello.py", ...):指定入口脚本、目标 exe 的名字
  • 如果你做的是 GUI 程序,base="Win32GUI" 就能隐藏控制台

3)执行打包

python setup.py build

跑完后,目录里会多一个 build/ 目录,里面是类似:

build/
  exe.win-amd64-3.11/
    hello.exe
    依赖文件...

你可以把整个 exe.win-amd64-3.11 目录打包发给别人(或者再用 Inno Setup 之类的工具做一个安装包)。

4)cx_Freeze 和 PyInstaller 有啥区别?

大白话说几条:

  • 思路不同:

    • PyInstaller 是“给我脚本,我帮你分析再打包”
    • cx_Freeze 更像“写一个 setup 配置文件,按构建步骤来”
  • 工程化更好:

    • 对于版本化、构建脚本、集成到 CI/CD 流水线,cx_Freeze 写法和 Python 生态其他工具比较统一
  • 兼容性:

    • 两个工具都不完美,你用哪个碰到坑多,就会更倾向另外一个 😅
    • 一般来说,PyInstaller 生态更大一点,cx_Freeze 稍微“小众但稳定”

如果你是做内部小工具,图方便,PyInstaller / auto-py-to-exe 足够; 如果你其实在做一个“桌面软件”,准备长期维护,那可以试着从一开始就用 cx_Freeze 写一个比较干净的打包配置。

最后简单帮你捋一下这三种方式怎么选

你可以这么粗暴地选:

  • 我就一个脚本,赶紧变 exe 给别人用→ 直接上 PyInstaller,一条命令解决问题

  • 命令行看着就烦,我想用界面点点点→ 用 auto-py-to-exe,先图形化配置,再把生成的命令学会

  • 我这个东西以后可能要走版本、打安装包,结构会越来越复杂→ 可以考虑从一开始就用 cx_Freeze + setup.py,后面接 CI/CD 也好搞

无论用哪种方案,有几个共性的“小建议”:

  • 最好在干净的虚拟环境里打包,避免把一堆没用的东西塞进去
  • 打好包后,多在几台不同的 Windows 上试一下,尤其是没装 Python 的机器
  • 遇到杀毒软件误报,不要慌,多换几台机器试试,确实没问题的话就加白名单

-END-

我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html

🔥虎哥私藏精品🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领