引入第三方模块pyinstaller将.py源程序转成可执行文件,pyinstaller把python 解释器和程序运行需要的模块打包在一起,使得用户不需要安装python和其它模块也可以运行打包好的程序。
pyinstaller支持windows、Mac OS和linux,却不算支持跨平台。在windows上pyinstaller打包好的可执行程序只能运行在windows上,在Mac打包的只能运行在Mac上,而且32位机器上打包好的不能到64位机器上运行。用Pyinstaller自己的平台上打包在自己的平台上用。
这里我们只介绍pyinstaller最粗浅最常用的部分,更详尽的用法请参见pyinstaller的技术文档。
1 pyinstaller的安装
pyinstaller是普通的第三方模块,可以在pycharm里图形化安装,也可以在命令窗口用pip3 install pyinstaller安装,详见python介绍里的安装第三方模块。
安装完毕可以运行pyinstaller -v查看版本和检验是否安装成功。pip3 install –-upgrade pyinstaller升级新版本
2 pyinstaller做什么
pyinstaller打包.py代码时会去分析代码都import了哪些模块,使用了哪些依附文件,打包时这些文件甚至python解释器都打包进来。把打包好的单一文件夹或者单一可执行文件直接发给用户,用户运行发送过来的可执行文件前甚至不必安装python解释器,更不必安装相关的支撑模块和文件,只需要用鼠标双击运行可执行文件或命令窗口正确路径下敲可执行文件的文件名就可以执行了。
3 使用pyinstaller
以应用实例 --> 网站API数据和CSV文件 --> 3.7.3 查询预测国内各地天气和pm值里的程序为例,代码保存为weatherPM.py,还有一个查询城市代码的支持文件city.json。在命令窗口(windows通过cmd调出的命令窗口或mac的terminal)上使用pyinstaller时,可以指定weatherPM.py的路径也可以先进入weatherPM.py所在的文件夹再执行。
用pyinstaller打包会在weatherPM.py所在文件夹下生成一个weatherPM.spec文件。之前如果没有build和dist这两个文件夹就建立文件夹build和dist;已经有就使用已经建好的文件夹。
weatherPM.spec是打包的参数设定文件,必要的时候可以修改。build文件夹存放打包过程中产生的日志和一些工作文件。dist里的内容是要分发给用户使用的打包好了的可执行文件或可执行文件夹, dist是英文distribute分发的前三个字母。文件夹dist里的内容根据打包过程中使用的不同参数生成可执行文件或可执行文件夹。如果先后用pyinstaller对weatherPM.py和locatIP.py进行打包,这dist里会有weatherPM和locateIP两个可执行文件或文件夹。
(1) 将weatherPM.py捆绑到文件夹dist下的文件夹weatherPM的方法:
在命令窗口上,进入weatherPM.py所在的文件夹执行 pyinstaller weatherPM.py
或 pyinstaller -D weatherPM.py
或 pyinstaller –-onedir weatherPM.py
也可以在命令里指定weatherPM.py文件的路径
Mac:pyinstaller /users/PythonABC/Documents/python/weatherPM.py
Windows:pyinstaller “C:\Documents and Settings\python\weatherPM.py”
dist文件夹下会生成一个名字为weatherPM的文件夹。weatherPM文件夹下有一堆文件,找到weatherPM可执行文件(Mac)或weatherPM.exe(windows)运行就可以了。发送给用户时要把整个weatherPm文件夹发给用户,如果对代码做了升级,如果引用的第三方模块和依托文件不变,只需把升级后的代码重新生成的可执行文件weatherPM(Mac)或weatherPM.exe(windows)发送给用户即可,dist下的其他文件不必重新发送。
(2) 加参数-F将weatherPM.py捆绑成文件夹dist下的一个可执行文件weatherPM(Mac)或weatherPM.exe(Windows:
pyinstaller -F weatherPM.py 或者
pyinstaller –-onefile weatherPM.py
优点是用户不用在一大堆文件里翻weatherPM可执行文件,用户也不用打开文件夹后面对一大堆看不懂的文件。缺点是象readme这种使用指导文件要分开发送,另外就是这种模式要比捆绑成文件夹的模式慢一些。
在捆绑成一个可执行文件前最好确保程序在捆绑成一个文件夹的情况下运行无误,相较而言,捆绑成文件夹的模式更容易诊断出错误。
打包完毕后去dist文件去看,再也看不到一个叫做weatherPM的文件夹,而只有一个weatherPM的可执行文件(Mac)或weatherPM.exe(Windows),直接运行这个可执行文件或者把这个可执行文件发送给用户就可以了。
4 添加自己的数据文件
对于.py代码里引用的功能模块,pyinstaller一般能帮忙分析出来,并打包进可执行文件夹,但对于代码中引用的数据文件则需要特别处理一下。
在weatherPM.py里打开city.json文件读取数据时,如果写相对路径’./city.json’(用.指代当前目录),则打包成可执行文件后运行时会出现找不到city.json文件的错误。
如果写绝对路径,比如’/Users/PythonABC/Documents/python/city.son’,打包成可执行文件运行就没问题了,但是这样做会丧失通用性。如果发给其他用户使用,其他用户必须在同样的路径/Users/PythonABC/Documents/python/下有一个叫做city.json的文件,否则还是会出现找不到city.json文件的错误。
解决这个问题首先要在代码里把绝对路径改成相对路径,不用’.’的更保险的相对路径。引进sys模块,sys.argv[0]是正在运行的代码文件的绝对路径+文件名。引进第三方模块pathlib,用sys.argv[0]生成路径对象,用路径对象的属性parent得到正在运行的代码文件的绝对路径。修改代码里city.json的路径引用,而后用pyinstaller打包时加上参数—-add-data把city.json打包进可执行文件夹。
weatherPM.py的代码参见13.5节查询预测国内各地天气和pm值里的程序。首先把weatherPM.py跟路径有关的语句city_list_location = ‘./city.json’修改成:
……
import sys
from pathlib import Path
……
city_list_location = Path(sys.argv[0]).parent.joinpath('city.json')
此时city.json跟weatherPM.py在一个文件夹下。
打包时用参数—-add-data指定city.json的位置,还需指定目标文件夹的位置,冒号分隔它们。city.json的目标文件夹就是可执行文件夹,即生成的dist下的weatherPM文件夹,打包时可以用’.’指代。
打开命令窗口上先进入weatherPM.py所在的文件夹,而后执行:
pyinstaller –-add-data ‘./city.json:.’ weatherPM.py
参数--add-data后跟的字符串用‘:’分开,‘:’前放数据文件city.json和所在路径。因为已经就在weatherPM.py文件夹下,所以用’./city.json’,目标文件用‘.’,但这个’.’指的是打包时生成的dist下的与weatherPM.py同名的文件夹weatherPM,weatherPM里存放可执行文件weatherPM(Mac)或weatherPM.exe(Windows)以及运行时所需的辅助文件。打包完成后,city.json会被自动放进这个weatherPM文件夹下的。
运行weatherPM文件夹下的可执行文件weatherPM(Mac)或weatherPM.exe(Windows)时,代码里的修改部分Path(sys.argv[0]).parent指的就是可执行文件所在的路径,而此时city.json就在这个路径里。所以从city_list_location = Path(sys.argv[0]).parent.joinpath('city.json')的这个city_list_location可以找得到city.json文件,不会再出现找不到文件的错误。
如果不是要打包成一个可执行文件夹,可是要打包成一个可执行文件,参数--add-data是没有办法把city.json打包进可执行文件的。可以正常打包pyinstaller -F weatherPM.py,在dist文件夹下生成可执行文件weatherPM(Mac)或weatherPM.exe(Windows),然后手动拷贝一份city.json到dist文件夹下。
5 pyinstaller常用命令
(1) pyinstaller locateIP.py:
打包成dist下面的一个文件夹locateIP,名字为locateIP(Mac)或locateIP.exe的可执行文件在文件夹locateIP里
(2) pyinstaller -D locateIP.py:
打包成dist下面的一个文件夹locateIP,同pyinstaller locateIP.py
(3) pyinstaller -F locateIP.py:
打包成dist下面的一个可执行文件,可执行文件的名字是locateIP(MAC)、loacteIP.exe(windows)
(4) pyinstaller -n myIPLocate locateIP.py:
指定打包的文件夹的名字,这条命令执行后dist文件夹下的打包好的文件夹名称不再是locateIP,而变成myIPLocate
(5) pyinstaller -F -n ipLocate locateIP.py:
指定可执行文件的名字,这条命令执行后locateIP打包好的可执行文件不再是locateIP或locateIP.exe,而是ipLocate(MAC)或 ipLocate.exe(windows)
(6) pyinstaller -D –-distpath ./newDist locateIP.py:
用指定了路径、自己命名的文件夹(这里是用./newDist)替换掉默认状态下的dist文件夹
(7) pyinstaller –-workpath ./workDir locateIp.py:
用指定了路径、自己命名的文件夹(这里是用./workDir)替换掉默认状态下的build文件夹
(8) pyinstaller –-specpath ./specification locateIP.py:
默认locateIP.spec是在当前目录下生成的,现在指定生成到目录./specification下
(9) pyinstaller -h:调出帮助文件
(10) pyinstaller -v:查看版本
要转成可执行文件的代码:
pyinstaller的使用:
添加自己的数据文件:
即将推出的Python ABC教程对PythonABC视频内容进行了梳理,修正了发现的错误、对代码做了些许优化、替换掉视频中的英文注释、替换掉国内不能访问的资源……敬请关注,谢谢