Python打包exe------>Pyinstaller插件
前言介绍
Python作为解释型语言,发布即公开源码,虽然是提倡开源但是有些时候就是忍不住想打包成exe,不仅仅是为了对代码进行加密,而是为了跨平台。防止有些没有安装py环境的电脑无法运行软件。
目前对python代码打包成exe的方式有多种,例如:py2exe,pyinstaller,cx_Freeze,nuitka以及Pyarmor,本次主要讲解下Pyinstaller打包Python程序。
打包步骤
PS: 如果打包为exe的话,版本尽量选择python3.6+32位版本,因为win64位系统向下兼容32位程序,但是如果不考虑32位系统的话无所谓,直接python64位版本直接打包就可以,只是只能在win64位系统上跑。
下载pyinstaller插件
pip安装
一般情况下使用pip进行安装:
pip install pyinstaller
默认情况下 pip 使用的是国外的镜像,在下载的时候速度非常慢,本文我们介绍使用国内清华大学的源,地址为:
https://pypi.tuna.tsinghua.edu.cn/simple
当然,你也可以使用其他国内源:
清华:https://pypi.tuna.tsinghua.edu.cn/simple
阿里云:http://mirrors.aliyun.com/pypi/simple/
中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
华中理工大学:http://pypi.hustunique.com/
山东理工大学:http://pypi.sdutlinux.org/
豆瓣:http://pypi.douban.com/simple/
我们可以直接在pip命令中使用-i
参数来指定镜像地址,例如:
pip install pyinstaller -i https://pypi.tuna.tsinghua.edu.cn/simple
Pycharm安装
在Pycharm这个IDE中,可以打开File->Settings->Project: ****(项目名)
下,点击Python Interpreter
这里我使用的是Virtualenv这个环境,使用Conda也可以。点击+
号,进行packing的安装。
在新打开的Avaiable Packages
面板中,可以搜索想要安装的插件,比如:pyinstaller
。找到之后点击安装即可。
可以点击面板上的Manage Repositories
配置一个国内源,下载会更快。
pyinstaller 打包命令
我们写的python脚本是不能脱离python解释器单独运行的,所以在打包的时候,至少会将python解释器和脚本一起打包,同样,为了打包的exe能正常运行,会把我们所有安装的第三方包一并打包到exe。
pyinstaller 命令
可以通过pyinstaller -h
来查看pyinstaller参数的意思。
pyinstaller 主要参数含义
打包命令
pyinstaller -F -w main.py -i main.ico --workpath build路径 --distpath exe打包路径 -n exe名字
主要参数
-F, --onefile
打包一个单个文件,如果你的代码都写在了一个py文件的话,可以使用这个命令,如果是多个py文件,就别用;-D, --onedir
打包多个文件,在dist中生成很多依赖文件,适合以框架的形式编写工具代码,代码易于维护;-a, --ascii
不包含unicode编码的支持(包括默认值:如果可用)-c, --console
使用控制台子系统执行(默认),只对windows有效-w, --windowed, --noconsole
使用windows子系统执行,当程序启动的时候不会打开命令行(只对windows有效)-i , --icon=<File.ico>
将file.ico添加为打包的exe文件的图表,只对windows系统有效--icon=<File.exe,n>
将file.exe的第n个图标添加为可执行文件的资源,只对windows系统有效-n Name,--name=Name
可选的项目,生成的.spec文件的名字和exe名字-p
设置导入路径(和使用PYTHONPATH效果相似),可以使用路径分隔符(windows使用分好,linux使用冒号),制定多个目录的时候可以指定多个-p参数来设置,让pyinstaller自己去找程序的资源--key KEY
用于加密Python字节码的密钥--add-data
可以将一些非二进制文件添加到exe文件中进行打包,参数为格式为static;static
--diistpath
指定打包后的程序存放目录,exe文件默认存放在当前目录下的dist
目录中--workpath
为输出的所有临时文件指定存放目录,默认为当前目录下的build
目录
打包单个python文件(带资源)
基本原理
Pyinstaller 可以将资源文件一起bundle到exe中,当exe在运行时,会生成一个临时文件夹,程序可通过sys._MEIPASS访问临时文件夹中的资源。
测试用例
接下来编写测试用例,访问资源文件夹static/a.txt
,并将其内容打印出来。
resource_path
方法说明了如何使用sys._MEIPASS
变量来访问临时文件夹中的资源。
- 编写一个python文件,main.py。
import sys
import os
#生成资源文件目录访问路径
def resource_path(relative_path):
if getattr(sys, 'frozen', False):
base_path = sys._MEIPASS
else:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
#访问static文件夹下a.txt的内容
filename = resource_path(os.path.join("static","a.txt"))
print(filename)
with open(filename,encoding='utf-8') as f:
lines = f.readlines()
print(lines)
f.close()
value = input("请输入内容: ")
print(value)
- 然后在该文件目录打开cmd命令窗口。执行命令:
pyi-makespec -F main.py
生成spec文件。
- 接着编辑spec文件,在datas选项中说明需要将哪些文件加入exe,在临时文件夹中命名成什么;
main.spec
文件,该文件为打包的配置文件,也可以使用该配置文件打包。 - 以下图为例,意思将main.py当前目录下的static目录(及其目录中的文件)加入目标exe中,在运行时放在零时文件的根目录下,名称为static。
- 然后执行命令
pyinstaller -F -c main.spec
;
- 命令行出现
Building EXE from EXE-00.toc completed successfully.
表示打包成功
打包之后会在当前目录下多出两个文件夹build
和dist
,其中build
文件夹存放的是输出的所有临时文件指定存放目录,dist
目录为存放生成的exe文件。
- 双击dist文件夹下的main.exe文件,结果如下图:
- 如果有多个资源;
datas=[('static/bg.jpg', 'static'), ('exam.db', '.')]
列表里面是元组,左边是你要添加的filename(相对路径即可),右边是拷贝到项目中之后的文件夹名字。
比如:('static/bg.jpg', 'static') 中的 'static/bg.jpg' 表示工程根目录下static文件夹下有bg.jpg图片,拷贝到项目之后的static文件夹。
('exam.db', '.') 中的'exam.db'是工程根目录下的文件,'.'表示根目录,即拷贝到项目中的根目录下。
打包单个python文件(不带资源)
不带资源的exe打包相对比较简单,不用对spec文件做额外处理,可直接执行pyinstaller -F xxx.py
即可,在此不在赘述。
如有疑问,欢迎浏览讨论。