pyinstaller防坑指南

编写好的Python脚本是可通过工具转换成一个可执行文档,这样在不同的电脑上可直接运行,甚至不需要安装Python与依赖。目前感觉上最好用的是pyinstaller,但使用时有坑。

pyinstaller防坑指南

看看官方对pyinstaller的定义:

PyInstaller reads a Python script written by you. It analyzes your code to discover every other module and library your script needs in order to execute. Then it collects copies of all those files – including the active Python interpreter! – and puts them with your script in a single folder, or optionally in a single executable file.

把Python脚本打包成可执行文档来使用,确实是挺方便的,特别是涉及分享应用的。每个电脑都可以直接运行exe的可执行文档。有时候pyinstaller打包出来的exe可执行文档会经常运行出错,当点击exe文档后闪退,也不知错在哪里。这时候应该怎么办?

我们打开系统自带的CMD,在CMD里运行exe文档,错误信息会显示在CMD里,即使运行出错也不会闪退。或者可以把exe文档拖动到CMD里面。

故障1: No such file or directory

pyinstaller在打包脚本的时候会搜索脚本所需要的依赖(libraries),但它主要是识别import语句所导入的模块,其它方式引用的模块将不被识别,另外引用的数据/文档也不会被识别,因此需要手动告诉pyinstaller需要什么。

Some Python scripts import modules in ways that PyInstaller cannot detect: for example, by using the __import__() function with variable data, using importlib.import_module(), or manipulating the sys.path value at run time. If your script requires files that PyInstaller does not know about, you must help it.

exe文件运行出错缺少什么包,我们就用--collect-all手动添加包的名字,直到所有的包都添加进去:

pyinstaller --collect-all package1 --collect-all package2 --collect-all package3 script.py

比如我们的脚本有import gradio,我们需要明确告诉pyinstaller需要用到的包,不然运行会提示缺少依赖。

When using Gradio with PyInstaller, especially with the --collect-all option, you often need to explicitly tell PyInstaller to include certain packages because Gradio relies on dynamic imports and may not be fully detected by PyInstaller's default analysis.

可以直接问人工智能需要哪些包,然后修改下执行的命令,如:what packages we need to collect with --collect-all option when using Gradio with PyInstaller?大模型会直接生成相应的指令:

pyinstaller your_gradio_app.py --onefile --collect-all gradio --collect-all gradio_client