「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战」 @[toc]
前言
用python实现一些功能很方便,但是想要不依赖于python环境执行,可以使用pyinstaller打包成exe,但是要注意,如果python环境中有很多无关的包,那么pyinstaller打包的体积就会比较大,因为一些无用的库也被打包进去了,这时候我们就需要python虚拟环境,将不同的项目放在不同的环境当中,每个虚拟环境只安装最少必要的库,这样就能确保打包出来的exe足够精简。 现在,我们的目标就是运行几个脚本,能够实现从.py程序到可执行程序及相关环境的.7z压缩包的转换。
Miniconda
Miniconda是conda环境的最小安装程序,我把它理解为一个管理python虚拟环境的工具,各个环境之间相互独立。关于安装和换源步骤网上很多我就不再赘述。环境管理命令可以看这里
这里我们只需要conda create和conda activate命令
conda create -n oldboy python=3.6.5
conda activate oldboy
pyinstaller
pyinsaller安装使用很简单:
pip install pyinstaller
pyinstaller 1.py
输出的exe和相关环境都在dist目录
requirements.txt
考虑到可能会有版本变动问题,我们需要安装特定版本的库,避免因库变动导致程序无法运行。运行以下指令导出python环境相关库
pip freeze >requirements.txt
在其他环境安装时,执行以下语句安装相关库:
pip install -r requirements.txt
7z压缩
打包出来的程序包括一个exe和相关的环境,我们希望能将它们打包,方便拷贝。这里我们只需要压缩的指令,a是append的意思
7z.exe a output.7z .\dir\*
这个指令将dir文件夹下面的文件全部打包到压缩文件内,如果不加.\前缀则压缩文件内会包含dir路径。
用batch将所有东西组合起来
这里我写了两个脚本:
@REM create_env.bat
SET ENV_NAME=auto_deli_report
SET CONDA_HOME=C:\ProgramData\Miniconda3
call %CONDA_HOME%\Scripts\activate.bat %ENV_NAME%
if %errorlevel% == 0 (
echo conda env exists
) else (
echo activate env not exists
conda create -n %ENV_NAME% python=3.8 -y
)
@REM build.bat
SET ENV_NAME=auto_deli_report
SET PACK_NAME=auto-delineation-report-1.0
SET CONDA_HOME=C:\ProgramData\Miniconda3
call %CONDA_HOME%\Scripts\activate.bat %ENV_NAME%
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
pyinstaller %PACK_NAME%.spec -y
copy plugin.json dist\%PACK_NAME%
7z.exe a %PACK_NAME%.7z .\dist\%PACK_NAME%\*
第一个脚本负责判断当前miniconda是否有创建相关python虚拟环境,如果没有则会创建一个虚拟环境。 第二个脚本首先通过call指令激活虚拟环境,如果直接执行activate.bat会导致进入虚拟环境后,后续bat指令不执行。接着在虚拟环境内安装相关库,并通过pyinstaller打包,打包完成后添加一些必要的文件到打包出来的文件夹中,并用7z压缩成单一文件。 使用两个脚本的原因在于,创建完虚拟环境后,后续命令无法执行,暂时没有找到解决办法。 通过以上脚本,我们可以配合jenkins,在修改完.py程序后,push到gitlab/github上,然后在jenkins上构建程序,构建过程使用上述脚本,最终归档7z文件,方便版本管理。
参考: