执行pyinstaller后他会先分析你的代码,看有什么需要的模块,库,解释器,然后搜集相关的资源,最后全部包起来生成exe档。
這邊提醒一下:(我在win10 64位下执行,未在32位上执行过exe,未证实是否可行)
- 引入套件時盡量使用 from …import …,如果直接使用import的話會把整個包都打包進去,而無謂的增加工具的大小。
- pyinstaller 打包後的exe 只能在與打包時相同的作業系統下執行,在windows 下打包的無法在linux使用,另外 64位元的電腦下打包也無法在 32位元上使用(但反過來似乎可以)。
先安装pyinstaller
我安装了anaconda
,所以我在Anaconda Prompt
窗口下安装
pip3 insatll pyinstaller
再安装PyWin32 或者 pipwin32
但有人说安装pyinstall时就已经自动安装,我也不知道是不是真的,选留着,以后出问题可以查查。
| -h,--help | 查看该模块的帮助信息 |
| - | - |
| -F,-onefile | 产生单个的可执行文件 |
| -D,--onedir | 产生一个目录(包含多个文件)作为可执行程序 |
| -a,--ascii | 不包含 Unicode 字符集支持 |
| -d,--debug | 产生 debug 版本的可执行文件 |
| -w,--windowed,--noconsolc | 指定程序运行时不显示命令行窗口(仅对 Windows 有效) |
| -c,--nowindowed,--console | 指定使用命令行窗口运行程序(仅对 Windows 有效) |
| -o DIR,--out=DIR | 指定 spec 文件的生成目录。如果没有指定,则默认使用当前目录来生成 spec 文件 |
| -p DIR,--path=DIR | 设置 Python 导入模块的路径(和设置 PYTHONPATH 环境变量的作用相似)。也可使用路径分隔符(Windows 使用分号,Linux 使用冒号)来分隔多个路径 |
| -n NAME,--name=NAME | 指定项目(产生的 spec)名字。如果省略该选项,那么第一个脚本的主文件名将作为 spec 的名字 |
打包py文件
命令行界面(例如cmd)进到要打包的py文件的文件夹内,
例如:我随便找个地方,建个文件夹,直接把做好的aa.py文件复制在里面,在cmd中,进到刚才新建的文件夹内,执行
pyinstaller -F aa.py
会在文件夹下产生一个dist文件夹,里面就放着可执行文件。
我在py文件里面有一些input,双击后,会显示命令行窗口,让我输入,等完输入完,窗口自动关闭。
如果程序里面只是执行代码,没有input,双击只会一闪而过。
解决办法待试验更新
.spec 檔
spec檔是你打包時的一些相關設定
當你程式不是那麼簡單時,打包時很可能遇到很多error,尤其像是”no module names XXX”這種,這時候就需要一直google。
我目前的經驗,spec 裡 [‘cython’, ‘sklearn’, ‘sklearn.ensemble’, ‘sklearn.neighbors.typedefs’, ‘sklearn.neighbors.quad_tree’, ‘sklearn.tree._utils’,’sklearn.utils._cython_blas’] 這些都給他設定在hiddenimport 裡應該可以擋掉大部分。
datas的寫法為(路徑,名稱),如: [(‘mtcnn-model\’, ‘mtcnn-model’), (‘img_for_registed\’, ‘img_for_registed’)],這樣他就會把這些folder給打包進dist。
如果你是使用 -D 的模式,你也可以不寫在datas裡,當他包好後在自己手動拉到dist 資料夾內也行。
另外有些module像是mxnet好像也無法直接自動幫你包進去,所以你需要自己到你python 的site-package裡找mxnet的資料夾,把它整個複製到dist裡就可以了~
當你改寫好spec檔後,可以透過
pyinstaller -D XXX.spec
指定用這個spec 來重新打包。
總之,當你的程式越複雜,呼叫到越多module時,越可能採到一堆坑,通常都google的到,相信你不會是第一個踩到坑的人!