Pyinstaller打包Python程序攻略

PyInstaller基本使用方法

下面列举几个常见的可选参数:

1
2
3
4
5
6
7
8
9
10
pyinstaller [options] my_script.py
[options]:
-h 显示帮助并退出
-D 生成一个文件夹,其中包含一个可执行文件(默认)
-F 生成单个可执行文件
-w 生成一个无命令行界面的程序
-i file.ico 指定图标
--add-data SRC;DEST 在程序中用到的其他(非二进制)文件,不建议用
--hidden-import MODULENAME 在程序中隐式导入的库,可多次使用
--exclude-module MODULENAME 不希望导入的库,可多次使用

更详细的使用方法可以参看官方手册,本文不再赘述。

问题:打包后程序体积太大

由于笔者使用的是Anaconda作为Python环境,最近有个项目需要将Python代码打包成可执行文件。在之前的需求中没有使用科学计算库(例如numpy、pandas等)所以打包出来的结果也就10M左右,完全可以接受。但是最近在项目中使用了numpy等科学计算库之后,程序打包的结果接近1G左右,这样的打包结果简直令人窒息。这里主要有两个解决方案:1. 使用虚拟环境打包 2. 使用纯净版本的Python打包

推荐使用第二种方法。

使用虚拟环境打包

Python虚拟环境有Anaconda、virtualenv以及pipenv,但是Anaconda打包的程序体积太大,所以我们需要避开Anaconda。本文主要介绍的虚拟环境是pipenv,它是pip和virtualenv的结合,所以使用起来也更加方便,另外值得一提的是,pipenv和requests(Python网络请求包)是同一个作者。

Pipenv使用教程

  • 安装pipenv
1
pip install pipenv
  • 创建虚拟环境

首先进入你的项目所在目录,然后输入下面的命令安装虚拟环境:

1
pipenv install --python path\to\python

注: “path\to\python”是python.exe可执行程序的路径,可以是Anaconda版本的Python也可以是本地纯净版本的Python。因为我们需要避开Anaconda所以读者最好自己前往Python官网下载纯净版本的Python,然后通过上面命令安装虚拟环境。

  • 激活虚拟环境
1
pipenv shell

输入上面的命令之后我们就进入了虚拟环境,然后我们可以像平时一样使用Python。

  • 安装依赖库

在虚拟环境下安装 Pyinstaller 和你自己的脚本依赖的第三方库

1
2
3
4
pipenv install pyinstaller
pipenv install numpy
pipenv install pandas
pipenv install matplotlib

当然也可以进入虚拟环境后直接使用pip进行安装。

问题:ModuleNotFoundError

pyinstaller打包成功后运行程序提示ModuleNotFoundError: No module named ‘distutils’错误解决办法。

问题分析:由于pandas需要调用distutils库(Python自带),但是最新版本的virtualenv和pyinstaller存在兼容性问题,即打包的时候会遗漏distutils库,目前这个BUG还没有得到解决。当然Github上也有很多解决办法,具体可以参考这里

解决方法:由于16.1版本的virtualenv可以正常使用,所以我们可以降级安装virtualenv。1. 首先我们需要卸载新版的virtualenv,然后安装16.1版本的virtualenv;2. 卸载原来的虚拟环境,然后使用16.1版本的virtualenv重新安装虚拟环境(使用pipenv安装);3. 最后安装相关的依赖库重新打包即可。

使用纯净版本的Python打包

由于本地已经存在Anaconda环境,所以如果我们想再安装纯净版本的Python可以使用虚拟机,但是使用虚拟机安装Python需要安装虚拟机软件,然后安装Windows镜像,步骤过于繁琐,所以我们可以另辟蹊径——使用临时环境变量。

首先前往Python官网下载纯净的Python环境并安装到本地,然后我们可以通过下面的批处理脚本设置临时环境变量,为了方便可以将下面的脚本保存到batch脚本文件中(例如命名为set_python_path.bat),并将该脚本放到c:\windows中,这样我们就可以在任何目录下切换Python环境了。

set_python_path.bat:

1
2
3
4
5
6
7
8
9
10
@echo off
set conda_path=d:\anaconda3
set python_path=d:\program files\python36
rem Approach one: Replace the anaconda installation path with the new python installation path
call call set path=%%path:%conda_path%=%python_path%%%
rem Approach two: Let the new python installation path overwrite the anaconda installation path
rem set path=%python_path%;%python_path%\Scripts;%path%

上面的代码中conda_path是Anaconda的安装路径,python_path是纯净版本的Python安装路径。设置临时的Python环境变量主要有两种方法:方法一是替换环境变量中Anaconda安装路径为纯净版本的Python安装路径;方法二是将纯净版本的Python安装路径放到所有路径之前这样就可以覆盖Anaconda的路径。

我们在运行完上面的脚本之后就可以切换到新的Python环境,然后安装Pyinstaller和相关的依赖包进行打包。

最后

使用上面两者方法之一,原先接近1G的程序,现在只有40M左右。

Enjoy it!

显示 Gitment 评论