PyInstaller把Python脚本打包成可执行程序教程
一、说明
一直以来都有把.py文件打包成.exe文件的想法,但总是不够强烈,每次拖着拖着就淡忘了。
昨天帮硬件部门的同事写了个脚本,然后今天下午的时候,他问有没有办法把脚本打包成可执行文件,这样方便以后交给别人的时候别人不用装Python也能运行。
习惯性操作,百度一下,看到标题都基本使用PyInstaller,然后直接进官方文档。
二、打包操作
2.1 待打包文件
文件其实无所谓,随便使用一个正确的Python脚本文件即可。我这里直接使用给同事写好的文件tracer.py(其实主要是为了对这个脚本做个记录方便以后自己找,如果使用我这个需要安装openpyxl库)。
import logging
import os
import openpyxl class MatterTracer():
def __init__(self):
self.config_dict = {
# ERP导出文件存放目录
"erp_xls_dir":"./ERP/",
# ERP导出文件的表名
"erp_xls_sheet_name": "sheet1",
# ERP导出文件存货编号列
"erp_part_number_column":"B",
# ERP导出文件规格型号列
"erp_description_column":"D",
# ERP导出文件物料状态列
"erp_approved_column":"E",
# ERP导出文件物料实际起始行
"erp_start_rank_no":2,
# 本地维护文件存放目录
"local_xls_dir":"./LOCAL/",
# 最终文件输出目录
"local_xls_save_dir":"./LOCAL_NEW/",
# 本地维护文件的表名
"local_xls_sheet_name": "Sheet1",
# 本地维护文件存货编号列
"local_part_number_column":"A",
# 本地维护文件规格型号列
"local_description_column": "D",
# 本地维护文件物料状态列
"local_approved_column": "H",
# 本地维护文件物料实际起始行
"local_start_rank_no":2,
}
# ERP导出文件清单
self.erp_xls_list = ["IC.XLSX","插件.XLSX","贴片.XLSX"]
# self.erp_xls_list = ["IC.XLSX",]
# 本地维护文件清单
self.local_xls_list = ["capacitor.xlsx","connector.xlsx","diode.xlsx","ic.xlsx","magnetic.xlsx","miscellaneous.xlsx","mosfet.xlsx","nonum.xlsx","protect.xlsx","resistor.xlsx"]
# self.local_xls_list = ["capacitor.xlsx",] def tracer_follow(self):
erp_xls_wbs = []
local_xls_wbs = []
# 反复打开文件是比较耗性能的,所以先统一打开ERP导出的文件
for erp_xls_name in self.erp_xls_list:
logging.warning(f"start to open {erp_xls_name}")
erp_xls_wbs.append(openpyxl.load_workbook(f"""{self.config_dict["erp_xls_dir"]}{erp_xls_name}""")) # 反复打开文件是比较耗性能的,所以先统一打开本地维护的文件
for local_xls_name in self.local_xls_list:
logging.warning(f"start to open {local_xls_name}")
local_xls_wbs.append(openpyxl.load_workbook(f"""{self.config_dict["local_xls_dir"]}{local_xls_name}""")) # 遍历所有从ERP导出的文件
for erp_xls_wb in erp_xls_wbs:
erp_xls_sheet = erp_xls_wb[self.config_dict["erp_xls_sheet_name"]]
erp_rank_no = self.config_dict["erp_start_rank_no"]
# 遍历ERP导出文件的所有行,以物料号为空作为结束标志
while erp_xls_sheet[f"""{self.config_dict["erp_part_number_column"]}{erp_rank_no}"""].value is not None:
# 遍历所有本地维护的文件
# 是否找到匹配行的标志
logging.warning(f"""{self.config_dict["erp_part_number_column"]}{erp_rank_no}: start to find match""")
find_flag = False
for local_xls_wb in local_xls_wbs:
local_xls_sheet = local_xls_wb[self.config_dict["local_xls_sheet_name"]]
local_rank_no = self.config_dict["local_start_rank_no"]
# 遍历本地文件的所有行,以物料号为空作为结束标志
while local_xls_sheet[f"""{self.config_dict["local_part_number_column"]}{local_rank_no}"""].value is not None:
# 如果ERP物料号与本地物料号相等
if erp_xls_sheet[f"""{self.config_dict["erp_part_number_column"]}{erp_rank_no}"""].value == local_xls_sheet[f"""{self.config_dict["local_part_number_column"]}{local_rank_no}"""].value:
local_xls_sheet[f"""{self.config_dict["local_description_column"]}{local_rank_no}"""].value = erp_xls_sheet[f"""{self.config_dict["erp_description_column"]}{erp_rank_no}"""].value
local_xls_sheet[f"""{self.config_dict["local_approved_column"]}{local_rank_no}"""].value = erp_xls_sheet[f"""{self.config_dict["erp_approved_column"]}{erp_rank_no}"""].value
find_flag = True
# 如果找到匹配行,则后续记录不用再继续找了
logging.warning(f"""{self.config_dict["erp_part_number_column"]}{erp_rank_no}({erp_xls_sheet[f'{self.config_dict["erp_part_number_column"]}{erp_rank_no}'].value}): found match""")
break
# 本地文件切换至下一行
# logging.warning(f"""{self.config_dict["erp_part_number_column"]}: not match with """)
local_rank_no += 1
# 如果找到匹配行,则后续文件不用再继续找了
if find_flag:
break
# 如果退出文件遍历还是没找到匹配项
if not find_flag:
logging.warning(f"""{self.config_dict["erp_part_number_column"]}{erp_rank_no}({erp_xls_sheet[f'{self.config_dict["erp_part_number_column"]}{erp_rank_no}'].value}): have no match""")
# ERP文件切换至下一行
erp_rank_no += 1 # 如果保存的目录不是打开的目录,则先判断要保存的目录是否存在,不存在则先创建
if self.config_dict["local_xls_save_dir"] != self.config_dict["local_xls_dir"]:
logging.warning(f"""local_xls_save_dir {self.config_dict["local_xls_save_dir"]} is not local_xls_dir {self.config_dict["local_xls_dir"]}""")
if not os.path.exists(self.config_dict["local_xls_save_dir"]):
os.mkdir(self.config_dict["local_xls_save_dir"]) # 遍历本地维护的所有文件
flag = 0
for local_xls_wb in local_xls_wbs:
local_xls_wb.save(f"""{self.config_dict["local_xls_save_dir"]}{self.local_xls_list[flag]}""")
flag += 1 pass if __name__ == "__main__":
mt = MatterTracer()
mt.tracer_follow()
2.2 安装PyInstaller
直接pip安装即可,其他依赖pip会自动安装上不用管。
pip install pyinstaller
2.3 基本打包操作
pyinstaller.exe位置:和习惯一样,安装PyInstaller库后,其对应的可执行文件(如果有)也后被放到Python环境的Scripts目录下。如果要使用要么使用全路径,要么把Scripts目录加入PATH环境变量,我这里已加入环境变量。
打包时直接pyinstaller带main函数入口所在python文件即可,如我这里就是(打包过程中360可能会告警注意放行一下即可):
pyinstaller tracer.py
# 默认文件放到一个目录下,但其实可通过以下形式,将所有文件都集合成一个exe文件
# 但实际操作又发现放到一个文件,logging等的打印都不在控制台输出,所以也并非那么好用
# pyinstaller --onefile --windowed tracer.py

执行以上命令后,pyinstaller默认会在当前目录下:
创建与脚本文件同名的.spec文件(如我这里就是tracer.spec),该文件是pyinstaller分析脚本文件生成的打包指导文件,后边会根据该文件进行打包。
创建build目录(如果该目录不存在),该目录用于打包过程生成的临时文件,最终我们并不需要该目录。
创建dist目录(如果该目录不存在),该目录存放的就是最终打包出的结果,其下包括可执行文件及其依赖库。

另外注意双击运行exe文件,和直接运行脚本文件是一样的,即代码需要读写的目录/文件也需要放到当前目录下来,不然运行报错。

2.4 定制化打包操作【可选】
上边我们说打包其实是根据.spec文件的指导进行的,如果我们想做一些定制打包操作(比如指定生成的exe文件名),可以直接修改.spec文件,然后使用类似如下形式打包:
pyinstaller tracer.spec
三、一些说明
打包原理:PyInstaller读取给定的Python脚本进行递规分析,找出所有Python脚本执行所需的模块和DLL库,然后复制一份统一放到dist目录下。
关于跨平台:不同操作系统可执行文件的格式是不一样的、动态库也是不一样的,所以PyInstaller虽然支持Windows/Linux/Mac但显然不能一处打包到处运行,只能要生成哪个平台的可执行文件就要在哪个平台打包。
参考:
https://pypi.org/project/PyInstaller/
https://pyinstaller.readthedocs.io/en/v3.5/usage.html
PyInstaller把Python脚本打包成可执行程序教程的更多相关文章
- 将Python脚本打包成可执行文件
Python是一个脚本语言,被解释器解释执行.它的发布方式: .py文件:对于开源项目或者源码没那么重要的,直接提供源码,需要使用者自行安装Python并且安装依赖的各种库.(Python官方的各种安 ...
- Python脚本打包成exe执行文件
需求 一个教辅目录结构检查工具,目录结构是[书籍]-[章节]-[题目|答案]-[*.jpg],后台有个异步处理的服务,需要强依赖这个目录结构. 书籍解析是单独的pipeline,日志对用户不可见,这里 ...
- 利用pyinstaller将python脚本打包发布
之前写了一个小工具,将excel配置表转换为json.xml.lua等配置文件.最近在学习egret,正好需要转换配置文件,刚好就用上了.然而当我想把工具拷到工作目录时,就发愁了.之前我为了方便扩展, ...
- 用PyInstaller把Python代码打包成单个独立的exe可执行文件
之前就想要把自己的BlogsToWordpress打开成exe了.一直没去弄. 又看到有人提到python打开成exe的问题. 所以打算现在就去试试. 注:此处之所有选用BlogsToWordpres ...
- 把 Python 脚本打包成可以直接双击运行的 .exe 文件 【转】
因为最近要用到 Python 脚本,所以自己学习了一下,顺便学习如何把它打包成 .exe 可执行文件,达到双击运行的效果,网上找了资料,保存下来学习用,原文出处:https://baijiahao.b ...
- 用pyinstaller把python代码打包成exe可执行文件
优点: 1. pyinstaller 是跨平台的可以用在linux和windows系统上 2. 操作非常简单,几个命令就搞定了,这个比py2exe容易用多了 缺点: 1. 打包后的体积过大,因为要带p ...
- 把python脚本打包成win可执行文件
前几天有个朋友找我写一点小东西,写好后把代码发他帮他搞了半天,结果愣是没听懂,就找到了这个办法. 1.导入pyinstaller包, pip install pyinstaller 2.进入到你需要打 ...
- python脚本打包成rpm软件包
前言 软件最终都会有交付的形式,有的是用tar包,有个是以目录,有的是封成一个文件包,从大多数使用场景来说,直接打包成软件包的方式是最简单,也是最不容易出错的,路径可以在包里面写死了 实践 关于打包的 ...
- 【转载】将python脚本打包成exe文件
exe文件也就是可以直接执行的文件.通常我们编好的带py后缀的脚本文件都是需要在有python的环境下执 行,每次通过Win + R打开运行窗口再输入powershell打开控制台,再千辛万苦地cd ...
随机推荐
- Delphi中窗体的事件
Delphi中窗体的事件 Form窗体可以响应各种各样的时间,在Object Inspector的Events页面中罗列了一大堆,如下图: 下面将要列出一些常用的事件. 1.OnActivate 当窗 ...
- vue项目进入mui.js报错 typeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode .....
在做项目时,引用mui报错如下 看样子就是不支持严格模式吧. 解决方法是在根目录 下的.babelrc文件里面添加过滤掉.不用严格模式
- vue+element创建动态的form表单.以及动态生成表格的行和列
动态创建form表单,网上有插件 (form-create) 不过我不知道它怎么用,没有使用成功,如果你使用成功了,欢迎下方留言. 最后我使用了笨方法,针对各个表单写好通用的组件,然后根据type用v ...
- 海思3519A 移植ffmpeg
文件下载 下载x264 git clone git://git.videolan.org/x264.git 下载ffmpeg git clone git://source.ffmpeg.org/ffm ...
- Django框架(十四)-- forms组件、局部钩子、全局钩子
一.什么是forms组件 forms组件就是一个类,可以检测前端传来的数据,是否合法. 例如,前端传来的邮箱数据,判断邮件格式对不对,用户名中不能以什么开头,等等 二.forms组件的使用 1.使用语 ...
- java接口顺口溜
原创作品,转载请注明来源,这篇博客我也发到了我的csdnhttps://blog.csdn.net/suyues/article/details/103458086 接口 接口定义全局变量和抽象方法 ...
- helm搭建本地chart仓库及基本操作
这个步骤,是配合公司的竞赛. 因为公司这次的环境,我们只有namespace权限,而没有整个集群的管理, 而且,公司没有提供统一的helm chart repo, 所以只能自建. 参考URL: htt ...
- 51nod 1594 Gcd and Phi(莫比乌斯反演)
题目链接 传送门 思路 如果这题是这样的: \[ F(n)=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\phi(gcd(i,j)) \] 那么我们可能会想到下 ...
- 安装Visual Studio 时窗口闪过就退出
双击安装文件,窗口闪了下就退出了. 解决方法:控制面板 ———程序——程序和功能——打开或关闭Windows功能——关闭NET相关框架. 然后再次安装即可. 参考文献: VS安装程序一闪而过
- java JSONObject
JSONObject.has("key")方法首先判断是否含有该key字段,如果不存在该字段,返回false;如果存在此字段,还判断了该字段的value值是否为null,如果val ...