【踩坑之旅】Pyinstaller的exe封装经验总结--避免过大和报错

为啥要来踩坑

先是接收到一个朋友想搞一个批量导入excel的工具,于是就开始吭哧吭哧的开始了pyinstaller的踩坑之旅,过后想起来有些许蛋蛋的忧伤

近期有想法将自己写的代码成为exe文件进行程序文件执行,但是在封装这一块是小白,完全不懂啊!!
百度一下搜索到了一个神器——pyinstaller
【踩坑之旅】Pyinstaller的exe封装经验总结--避免过大和报错_第1张图片
先贴上封装后的结果图,你要是问我怎么用呢,我想说其实这个程序能完成的工作,直接用复制粘贴即可。这里只是为了测试pyinstaller随便搞了一个小小的功能。。。
【踩坑之旅】Pyinstaller的exe封装经验总结--避免过大和报错_第2张图片
通过某度得知现在python最流行的exe封装工具pyinstaller,顺便查询了一下官方文档:

# pyinstaller关键字
-v, --version		显示程序版本信息并退出。
--distpath DIR		捆绑应用的放置位置(默认值:./ dist)
-y, --noconfirm 	替换输出目录(默认值:SPECPATH / dist / SPECNAME)而不要求确认
--clean				在构建之前,请清理PyInstaller缓存并删除临时文件。
-D, --onedir		创建一个包含可执行文件的单文件夹捆绑包(默认)
-F, --onefile		创建一个文件捆绑可执行文件。
-p DIR, --paths DIR	搜索导入的路径(例如使用PYTHONPATH)。允许使用多个路径,以“:”分隔,或多次使用此选项
-c, --console, --nowindowed
					打开用于标准I / O的控制台窗口(默认)。在Windows上,如果第一个脚本是“ .pyw”文件,则此选项无效。
-w, --windowed, --noconsole
 					Windows和Mac OS X:不提供标准I / O的控制台窗口。在Mac OS X上,这也会触发构建OS X .app捆绑软件。在Windows上,如果第一个脚本是“ .pyw”文件,则将设置此选项。在* NIX系统中,此选项被忽略。
-i					FILE.ico:将该图标应用于Windows可执行文件(格式必须是ico格式)

比如我需要在封装前进行缓存清理,然后封装成一个exe执行文件,且不需要显示CMD小黑框则用如下代码:

pyinstaller --clean -Fw excel.py

接下来就是代码时间。简单粗暴的为了测试封装结果的随便写了一下,并没有什么强大的功能,实际上只有复制粘贴,但是短短几行,能给我搞出几百MB,简直难以置信!!!

# -*- coding: UTF-8 -*-
import tkinter as tk 
from tkinter import END  
import pandas as pd

# #------------------------------窗口-----------------------------------#
window = tk.Tk()
window.title("Excel导入工具")
window.geometry("1000x600")
tk.Label(window, text="使用说明:", font=("楷体", 12)).place(x=0, y=40)
tk.Label(window, text="1.仅适用于Excel下的xlsx(2007及以上版本)或xls(2003)格式文件(必须);", font=("楷体", 12)).place(x=0, y=60)
tk.Label(window, text="2.需输入文件路径,示例:'C:\\Users\\excel\\1.xlsx';", font=("楷体", 12)).place(x=0, y=80)
tk.Label(window, text="3.需输入sheet名称,示例:Sheet1(区分大小写);", font=("楷体", 12)).place(x=0, y=100)
tk.Label(window, text="4.需要保证导入及写入文件表头顺序名称一致。", font=("楷体", 12)).place(x=0, y=120)
tk.Label(window, text="导入文件路径:", font=("楷体", 12)).place(x=20, y=200)
tk.Label(window, text="导入文件sheet名称:", font=("楷体", 12)).place(x=20, y=250)
tk.Label(window, text="写入文件路径:", font=("楷体", 12)).place(x=20, y=300)
tk.Label(window, text="写入文件sheet名称:", font=("楷体", 12)).place(x=20, y=350)
show_text = tk.Text()
show_text.place(x=450, y=200, height=200, width=400)

# Entry输入框,输入的值必须要定义,这里定义成字符串类型
var_read_path = tk.StringVar()
var_read_sheet = tk.StringVar()
var_write_path = tk.StringVar()
var_write_sheet = tk.StringVar()
# Entry输入框,输入的值必须要定义
read_path = tk.Entry(window, textvariable=var_read_path)
read_path.place(x=200, y=200, height=25, width=230)
read_sheet = tk.Entry(window, textvariable=var_read_sheet)
read_sheet.place(x=200, y=250, height=25, width=230)
write_path = tk.Entry(window, textvariable=var_write_path)
write_path.place(x=200, y=300, height=25, width=230)
write_sheet = tk.Entry(window, textvariable=var_write_sheet)
write_sheet.place(x=200, y=350, height=25, width=230)

def get_tar():
    read_path = var_read_path.get()
    read_sheet = var_read_sheet.get()
    write_path = var_write_path.get()
    write_sheet = var_write_sheet.get()
    read_data = pd.read_excel(r'{}'.format(read_path), sheet_name=read_sheet)
    write_data = pd.read_excel(r'{}'.format(write_path), sheet_name=write_sheet)
    concat_data = pd.concat([read_data, write_data])
    concat_data.to_excel(write_path, sheet_name=write_sheet, index=False)
    show_text.insert(END,
                       '导入文件路径:' + read_path + '\n'
                     + '导入sheet名称:' + read_sheet + '\n'
                     + '写入文件路径:' + write_path + '\n'
                     + '写入sheet名称:' + write_sheet + '\n'
                     + '执行成功\n请关闭该窗口!!!')

get_detail = tk.Button(window, text='执行', font='30', command=get_tar)
get_detail.place(x=220, y=400)

window.mainloop()

这次封装主要尝试了三种坑位,也是某度上说的比较多的三种坑位:
1、直接anaconda环境下进行封装,已开始直接给我干到了323MB;

2、使用anaconda创建虚拟环境然后从虚拟环境进行封装,这次是用的是Anaconda Navigator安装第三方包和依赖的包,还是不理想,封装后的文件还是有211MB;

3、最后看了网上的思路,上python官网重新下载一个python文件,完后pip install xxxxxxx 对应的库 最后完成封装25.4MB(我是使用这个成功的);

4、最后发现在anaconda新建的虚拟环境下用pip安装第三方库,似乎也可以解决此问题。从pip安装的效果上来看并不会将pandas里面的依赖大库mkl一起下载下来,有兴趣的看官可以尝试一下。

提醒:
1、在是用新装Python或者在anaconda新建的虚拟环境是用pip进行安装只需要安装对应的.py文件里面所包含的库和pyinstaller即可,在使用两种;
2、在封装之前,在封装的环境中运行一下你需要封装的代码,如果运行通了,基本封妆后也不会有什么问题。

经历过了这些坑位,总算总结出了一点小小的经验

  1. 首先是因为pyinstaller在封装的时候会将所有相关联的包会全部封装进去,不管用没用,总之,放进去再说,然后会将anaconda的root环境下的所有第三方库打包进去,其中还包括了很多MKL等大库,好几十MB的都有好多。并且,在打包的过程中还经常会出现DLL等报错,具体的解决办法可以在CSDN搜索一下,里面一大把,就不做赘述了。

  2. 其次就是在anaconda的虚拟环境上进行封装,具体的方法就是
    打开anaconda也就是这个软件当中绿色的那个,没错,就是绿色!!
    在这里插入图片描述
    然后找到Environments菜单,点击下面的create创建好了。
    【踩坑之旅】Pyinstaller的exe封装经验总结--避免过大和报错_第3张图片
    这里主要是因为我这里包含了pandas库,在anaconda在Anaconda Navigator安装包的话会把pandas里面依赖的第三方库全部安装下来
    【踩坑之旅】Pyinstaller的exe封装经验总结--避免过大和报错_第4张图片
    可以在anaconda中使用pip安装pandas所下载的包,没有包含MKL这个大库,所以整个小了很多。
    【踩坑之旅】Pyinstaller的exe封装经验总结--避免过大和报错_第5张图片

  3. 其次就是新下载的Python下进行封装了。
    此方法需要将python加入环境变量

#这是我个人的python安装路径下的文件夹
 D:\Python37-32\Scripts\ 
 D:\Python37-32\ 

为了避免混淆,可以将anaconda的环境变量进行删除,用完再加上就好了。
【踩坑之旅】Pyinstaller的exe封装经验总结--避免过大和报错_第6张图片
看起来和anaconda虚拟环境下用pip安装库差不多,这样子打包下来的文件相对比较小。
总而言之,在pyinstaller对python进行封装exe的动作还是需要新建一个纯净的Python环境进行封装,不然会将所有安装路径**\Lib\site-packages\下的包都写入到exe可执行文件里面去,这样会造成exe文件较大,运行速度极慢。
小小经验,希望对没有踩过坑的小伙伴一点点帮助。

  • 此致! 敬礼! 感谢您的阅读!

你可能感兴趣的:(踩坑之旅,python,exe,anaconda,程序人生,经验分享)