PyInstaller 到底干了什么?真的将Python代码编译了吗?

最近才发现(火星),PyInstaller 可以把 Py 打包成一个 exe,直接再 windows 上跑。
但是这个时候我就有点儿困惑:PyInstaller 是把 py 代码编译成了 windows 上用的 binary ?还是把需要 py 文件都收集起来,加了个“ mini 版”解释器,运行 exe 时再这个“ mini 版”解释器里运行?

我粗看了一下 PyInstaller 的官方文档,感觉是前者,但还是不太确定,而且百度无果,所以有前来求证。
(暂时只考虑 Windows、Python3 的情况)
PyInstaller 到底干了什么?真的将Python代码编译了吗?


16 回复

从网上查查就知道了,仅仅是打包本机中的 Python 二进制解释器和相关依赖包。


PyInstaller 干了两件核心的事:打包和封装,但它并没有将你的Python代码编译成机器码

  1. 打包依赖:它会分析你的主脚本,递归地找到所有import的模块、库、数据文件,然后把它们(包括Python解释器本身)全部收集到一个文件夹(--onedir模式)或一个独立的可执行文件(--onefile模式)里。

  2. 封装引导:生成的可执行文件里包含了一个引导加载程序(bootloader,用C写的)。当你运行这个exe时,引导程序会:

    • 在临时目录解压所有打包的Python文件(如果是--onefile模式)。
    • 启动内嵌的Python解释器。
    • 让你的主脚本在这个解释器里运行。

所以,你的.py文件在打包后通常还是原来的.pyc字节码文件(或者被加密/压缩了,但本质没变),并不是C或机器码。Python解释器依然在运行时逐条解释这些字节码。PyInstaller只是把所有东西“包”起来,让用户不用单独安装Python环境就能运行。

总结:它是个高级打包工具,不是编译器。

就是现在还是无法做到将 py 直接编译成 binary 嘛

建议你多搜索一下这方面的内容,不是什么新鲜东西。Python 可以编译成二进制文件 pyc,可以加快加载速度以及隐藏源码,当你不想让别人知道你的 Python 源码时,可以进行编译。

你第一次导入模块时,也会生成一个模块相应的 pyc 文件,用来加快导入速度。

当前运行的 Python 程序,也是先由 Python 编译成机器码然后再运行。

感谢!刚才也在 PyInstaller 的文档中找到了。

然鹅 pyc 能开倒车。。。也就加快一点速度了

“ mini 版”解释器,把各种依赖放在一起了。。。

很多时候还会缺失 python3.x.dll

只是打包运行环境和库

开倒车的问题可以通过混淆+替换解析器 opcode 在一定程度上解决


看看这个 http://nuitka.net

这货有时候还挺好用的,前几天给财务的妹子写了个操作 excel 的工具,第一次用这个打包之后发现用起来还挺溜

好像是打包所有安装好的扩展包而不是程序依赖的扩展的。之前将一个在 anaconda 环境下的 py 文件转成 exe,结果文件有 200+M。

nuitka 真的编译了。

我还看到了 Cython,这两个有什么区别嘛?

请教一下,nuitka 相关文档好少,想问一下,编译成可执行文件的时候 nuitka 会自动解决依赖问题吗!

回到顶部