最近用python写了一个TensorFlow程序,基于谷歌的facenet来检测人脸,我写的是服务器端,包括一个tcp通讯协议,问题来了,如何将其打包成一个exe文件发布?
本人电脑:
Windows 10 系统;
Python 3.6.3(Anaconda 3.5.0.1安装);
TensorFlow 1.4.0(GPU版本,1050Ti)
PyInstaller 3.3.1
网上最为流行的就是PyInstaller方法了,我决定使用这个方法将我的py文件打包成exe。首先,明确最新版的pyinstaller已经支持python3.6版本的打包工作,我们可以登录PyInstaller的官网看看下面的消息:
截止本人写这篇博客,最新版的PyInstaller是3.3.1:
使用pip安装步骤非常简单,就是一步:
pip install pyinstaller
然后使用也很简单,在windows下按Win+R进入命令行,输入cmd,然后进入你的py文件所在的文件夹:(我的程序放在了桌面的AeyeFaceDetection_python文件夹内)
cd desktop\AeyeFaceDetection_python
接着使用下面的命令生成exe文件:
pyinstaller -F main.py
用-F意味着可以生成单个可执行文件,如果是下面的方法:
pyinstaller -F -w main.py
则表示去掉控制台窗口,这在GUI界面时非常有用。不过如果是命令行就不要这样写。
现在我们假设已经按照-F方法生成成功,那么在我们的py文件所在的文件夹内可以看到两个新生成的文件夹,名字为build和dist,并且在我们要生成的py文件下有一个同名的spec文件,这个文件的作用在网上可以百度的到,我这里就不作叙述了。
我按照官方教程和各位网友的操作,发现第一个问题就是这样的:
File "d:\software\anaconda3.5.0.1\lib\site-packages\PyInstaller\utils\hooks\__init__.py", line 619, in collect_submodules
repr(pkg_dir), package))
File "d:\software\anaconda3.5.0.1\lib\site-packages\PyInstaller\utils\hooks\__init__.py", line 90, in exec_statement
return __exec_python_cmd(cmd)
File "d:\software\anaconda3.5.0.1\lib\site-packages\PyInstaller\utils\hooks\__init__.py", line 77, in __exec_python_cmd
txt = exec_python(*cmd, env=pp_env)
File "d:\software\anaconda3.5.0.1\lib\site-packages\PyInstaller\compat.py", line 588, in exec_python
return exec_command(*cmdargs, **kwargs)
File "d:\software\anaconda3.5.0.1\lib\site-packages\PyInstaller\compat.py", line 378, in exec_command
out = out.decode(encoding)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 125: invalid continuation byte
由于问题过于庞杂,不太好找原因,我就先写了小的测试脚本,命名为d.py,放在原文件夹下:
import time
print("zhangping is a man.")
time.sleep(5)
注意这里的延时是必要的,否则程序会一闪而过,就类似于C++中添加一个getchar()一样。
运行
pyinstaller -F d.py
发现可以成功,如下图:
就走我以为一切都顺利的时候,运行C:\Users\zhangping\Desktop\AeyeFaceDetection_python\dist\d.exe,发现程序崩溃:
这个问题在网上我搜了好久,包括增加环境变量等各种方法都尝试过了,都没有用,最后找到了这个:
https://www.zhihu.com/question/53717334
完美解决的方法如下:
(1)首先要查看自己的requests版本,高于2.10就自行卸载:
(2)卸载:
pip uninstall requests
(3)重新安装requests2.10.0版本:
pip install requests==2.10.0
再次打包就可以运行d.exe了。
然而打包main.py还是报错。
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 125: invalid continuation byte
2、第二个坑:UnicodeDecodeError: 'utf-8' 问题
网上好多方法均不可行,因为我的路径下没有任何中文,(虽然我的人脸数据库中的库中人名是中文),但网上很多的这种解决方案是不适合我的。
比如:http://blog.csdn.net/u010654583/article/details/79444330
用管理员权限是无法解决这个问题的。还是会报这个错误。
在查找了很多文章后,我看见了这个:
http://blog.csdn.net/u011529752/article/details/54892488
我按照他的思路,首先改变编码格式,先输入chcp 65001,表示使用UTF-8。
chcp 65001
然后运行:
最后显示打包成功!
原以为打包成功,结果我双击C:\Users\zhangping\Desktop\AeyeFaceDetection_python\dist\main.exe,遇到这样的问题:
其实这个问题在上面那个链接里面就已经有写了。但他写的方法只能对matplotlib在打包时候不出错,但不能使程序在运行时不出错!!!
根据错误的提示,在main.py的第8行,我找到了这句代码:
import matplotlib.pyplot as plt
很凑巧的是,这句代码和我的程序无关,当初加进来也没用上,所以我就直接删除了。
然后再次打包,运行exe文件,完美!
(1)要注意看看自己的requests版本,不出意外的话都说比较高的版本,要卸载,重装为2.10.0版本;
(2)要改变编码格式,先输入chcp 65001;
(3)要注意程序中是否出现了matplotlib的引入,如果有,则继续寻找解决办法(我没用到,就没有继续深究了)
(4)程序所在的目录最好不出现中文。
5、新坑:
https://blog.csdn.net/qq_41185868/article/details/80599336
6、新坑:
https://blog.csdn.net/Sagittarius_Warrior/article/details/78457824
7、新坑: