摘要:最好是客户双击,完事儿。目前已经兼容,以及和。一共会有个对象,分别是。,就是我们的工作目录,存放我们的数据。编译打包最后,我们执行就好了。打包的可执行文件会在里,中是一些打包时候需要的文件。输出中最后有字样,就算成功了。
写了个吊炸天的Python项目,把我和左手相处的时间都赔上了。但出于版权考虑,我不太想让使用方直接用我的代码,毕竟Python代码给出去,就真的收不回来了。
想给客户演示的时候,不想那么墨迹的打开dos cmd 或者 terminal ,然后运行 python app.py 这样的命令行。最好是客户双击,完事儿。就像有人在那自己动一样……
PyInstaller 来了,他就是这么一款帮助我们把整个项目完整打包的工具。目前已经兼容Py3.7,以及 Mac App 和 Windows Exe。
文档:https://pyinstaller.readthedo...
先说下,这篇文章有别于网上那坨安装、打包的草包,这次是真核!
1. 安装这个很简单,直接 pip install pyinstaller 就好。
⚠️注意了:你要编译成exe,建议你省心点的在windows上用pyinstaller,如果你要mac app的,那就用mac编译。
我今天就以windows为例
2. 简单使用这个也很简单,网上一抓一大把,我这里就不赘述了,无非就是那么几个命令:
pyinstaller -F 项目主文件(或者是单一脚本)
3. 参数说明-F,打包所有的依赖包在一个exe中,包括你自己的模块、内置模块以及第三方模块。
-c,如果你是命令行窗口,就要加上这个参数。
-w,窗口程序,比如你用了PyQt。
4. 高级用法:配置文件.spec,这个文件非常重要,我们可以通过编辑这个文件来打包我们的项目,类似DockerFile。
我给大家贴一个我的:
# -*- mode: python -*- block_cipher = None a = Analysis(["C:appmain.py"], pathex=["C:"], binaries=[], datas=[ ("C:datainputuiltin*.xlsx", ".datainputuiltin"), ("C:datainput*.xlsx", ".datainput"), ("C:dataoutput", ".dataoutput"), ("C:log", ".log"), ("C:appdb", ".appdb") ], hiddenimports=["numpy", "pandas"], ... ) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE(pyz, ... )
这其实就是一个python文件,只不过后缀是spec罢了。
.spec一共会有4个对象,分别是:Analysis、PYZ、EXE、COLLECT。
Analysis用处最多,一个个解释:
第一个参数,是指定我们整个项目的主程序,也就是我们的入口文件。
pathex,就是我们的工作目录
datas,存放我们的数据。
好了,说到这里就要好好说一说这个Pyinstaller的工作流程了。当我们双击编译好的exe后,他是会创建一个临时目录,把所有需要用的包都解压到那里,然后执行。执行完毕后,临时文件夹就消失了。
这和我们有什么关系呢?想一下,如果你的项目中需要去读取某些文件,甚至是用户的输入参数,怎么办?打包出来的exe 是没有办法通过直接指定参数,类似:python main.py --input=*.xlsx 来读取文件的,因为我之前说了,在执行的时候会把项目解压到一个临时目录,所以原来项目中写好的相对路径也不管用。
为此,我们需要把host上的实际文件给copy到那个临时目录下,所以这个datas的作用就是这个,我的文件中,我把host下的 C:datainputuiltin*.xlsx文件都copy到临时目录的 datainputuiltin 下面。
hiddenimports ,继续说下去,PyInstaller有时候无法侦察到全部的依赖包,怎么办?我们可以在这个后面加,把PyInstaller编译出来的exe在运行的时候报的缺少模块给写里面。
⚠️注意了: pandas 和 numpy 有个很奇怪的地方,就是引用了 pandas 的地方,如果没有引用 numpy ,就会报错。所以你可以在主入口上面加一个 import numpy 。
⚠️注意了:直接 import numpy 还是会报错。怎么办?在 import numpy 下面加 import numpy.core._dtype_ctypes
5. 临时目录那刚刚说的临时目录在代码里怎么处理呢,如果代码中还是老样子处理相对路径,一定是找不到的。
官方文档中给出了这么一段:
Your app should run in a bundle exactly as it does when run from source. However, you may need to learn at run-time whether the app is running from source, or is “frozen” (bundled).
import sys if getattr( sys, "frozen", False ) : # running in a bundle basedir = sys._MEIPASS else : # running live
所以在你的项目中,如果有配置文件的话,就在那里加上这一段,然后在bundle中添加你的新路径,else还是你的老代码。
这个 sys._MEIPASS 是个特殊的值,是在Pyinstaller打包的时候才会添加的临时变量,通过这个变量我们可以获取到在执行exe时候的临时目录。
这对代码的改动是最小的。
6. 编译打包最后,我们执行 python xxx.spec 就好了。打包的可执行文件会在dist里,build中是一些打包时候需要的文件。
输出中最后有 successfully 字样,就算成功了。他也会告诉你,exe出现在哪个位置。
当然不是说这样就万无一失了,别人也可以反编译你的exe,所以我们可以在打包的时候用Cython去编译一次,把混淆过的代码打包。这样的话难度就增加了,同时再加上mac地址绑定,这里就有多种思路了。下一次我给大家说说。
关注公众号「Python专栏」,回复关键字:「spec」获取完整项目spec文件。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/43299.html
摘要:我们来用实现一个修改开机密码的小程序。的逻辑不复杂,核心代码就一句话,通过模块调用的,来达到修改密码。控制,并修改密码那么就是你想要修改的用户名,一般有两种操作,一种是直接修改他的,一种就是修改他现有的用户。等待用户双击即可。 showImg(https://img-blog.csdnimg.cn/20190302193115788.png?x-oss-process=image/wa...
摘要:为了进一步提高阅览体验这个小目标,让大家更方便的畅游,因此诞生了。温馨提示不要打开这种巨无霸的开源,因为从接口拉取所有目录文件名数据都需要几分钟。。。大屏全貌在大屏幕下,会展示所有的内容,在等小屏幕下默认只显示侧边栏目录树,而默认是隐藏的。 github源码地址:https://github.com/jawil/GayHub showImg(https://segmentfault....
阅读 565·2021-11-18 10:02
阅读 1045·2021-11-02 14:41
阅读 671·2021-09-03 10:29
阅读 1891·2021-08-23 09:42
阅读 2726·2021-08-12 13:31
阅读 1196·2019-08-30 15:54
阅读 1949·2019-08-30 13:09
阅读 1425·2019-08-30 10:55