原文链接:http://www.juzicode.com/python-tutorial-pyinstaller/
想象一个场景,你写的Python程序做好之后如果要发布给别人用,别人拿到你的代码就能直接用了吗?好像至少还要安装一个解释器吧。如果你的代码使用了第三方库文件,还得让别人先安装第三方库文件。有没有一种方法可以解决这些问题,对方拿到你的程序直接运行就可以了?当然有,pypi就好像多啦A梦那个“机械人专用四次元空间内藏秘密道具格纳口袋”,随意翻一翻就能找到好东西,其中pyinstaller就是一个非常优秀的打包工具,下面我们就以Windows系统为例介绍下pyinstaller的用法。
pyinstaller因为不是标准库,需要先使用pip安装:
pip install pyinstaller
基本用法
pyinstaller最基本的用法:(下面的描述中没有特别说明之处均以yourprogram.py表示你的入口py文件名称)
pyinstaller yourprogram.py
命令执行成功后,会将所有待发布的文件打包在当前工作目录下的“dist\\yourprogram\\”文件夹中,该文件夹下可以看到有很多的dll文件和一个“yourprogram.exe”文件,这个exe文件就是最终生成的可执行文件。
下面是一个简单的例子,py文件名称是pyinstest.py,在当前工作目录下运行pyinstaller pyinstest.py,等待提示“completed successfully”表示生成文件成功,在当前工作目录的dist\\pyinstest目录下会生成一个pyinstest.exe文件:
print('\njuzicode.com / vx:桔子code\n')
print('这是一个pyinstaller的简单例子')
inp=input('请输入用户名:')
print('您输入的用户名为:'+inp)
生成单个可执行文件
用前面最基本方法会生成一个文件夹和一大堆文件,看起来没有那么“清爽”,还有一种方法是打包成单个的exe文件,需要使用-F选项,命令形式是这样的:
pyinstaller -F yourprogram.py
这种方式会在当前工作目录的dist文件夹下生成一个“yourprogram.exe”文件。
窗口程序
用tkinter做的窗口程序,如果直接用前面的命令生成可执行文件,运行时会在后台显示控制台界面,对于桔子菌这种有强迫症的人来说,总感觉有点别扭:
如果要消除控制台窗口,可以通过增加-w参数消除:
pyinstaller -F -w yourprogram.py
当然了,如果还不是到最后发布程序的时候,可以先保留着这个后台窗口,在后台窗口里面可以看到所有的调试信息。
用前面的方法打包后生成的可执行文件关联的是pyinstaller的默认图标:
如果窗口程序包含自定义的图标,比如下面这个例子包含了名称为image.ico的图标:
class GuiWindow():
def __init__(self):
self.root=Tk()
self.root.title('pyinstaller例子 by桔子code')
self.root.geometry('500x300')
self.root.iconbitmap('image.ico')#窗口图标
可以通过增加 –icon=”ico文件名称”或者-i “ico文件名称”选项,将自定义图标打包进exe文件中:
pyinstaller -F -w yourprogram.py --icon="iconfilename"
pyinstaller -F -w yourprogram.py -i "iconfilename"
用自定义图片生成后的应用程序是这个样子的:
多进程
先看下面这个多进程的例子,子进程每次循环自加1,循环10次退出,主进程中启动了2个func子进程,等待5s后退出,这段代码看起来人蓄无害:
import os,time, multiprocessing
def func():
print('进入进程: ' , os.getpid())
loopcnt = 0
while loopcnt < 10:
loopcnt = loopcnt + 1
time.sleep(0.3)
print('退出进程: ' , os.getpid())
if __name__ == '__main__':
print('\n juzicode.com vx:桔子code')
print('进入主进程, pid = ', os.getpid())
p1 = multiprocessing.Process(target=func, name='func1')
p2 = multiprocessing.Process(target=func, name='func2')
p1.start()
p2.start()
time.sleep(5)
print('退出主进程, pid = ' ,os.getpid())
人蓄无害代码用python直接运行的效果:
充满好奇心的你可以尝试下打包后运行exe文件看看是什么效果,当然建议你在尝试前保存好当前的工作内容。
在Windows中如果在Python代码中使用了multiprocessing模块,用pyinstaller打包会出现RunTimeError、电脑卡顿或者CPU被填满等问题。要解决这个问题可以在程序的入口处“if __name__ == ‘__main__‘:”语句之后增加一行:multiprocessing.freeze_support(),再重新打包运行exe文件,效果又和前面用Python直接运行是一样的了。
说明:本文例子在windows10、Python3.8、pyinstaller4.2中测试。