今天试了试将python程序打包成windows的可执行文件(exe格式)
使用pyinstaller
1、安装
pip install pyinstaller
官网地址:http://www.pyinstaller.org/
2、打包
打包方式a:
pyinstaller 路径+文件
ps:适用执行完程序就可以关闭的python程序
打包方式b:
pyinstaller -F 路径+文件
ps:适用需要一直执行的程序,如客户端或服务器形式,不会关闭掉程序,(带有小黑框和调试信息)
打包方式c:
pyinstaller -F -w 路径+文件
ps:适用于GUI程序,没有小黑框
记:
使用--add-data 选项,将文件加入打包里
eg: pyinstaller --add-data "log.log;."
windows使用分号;
linux使用冒号:
第一个参数是要加入的文件(在当前系统的位置-绝对,相对都可以),第二个是打包程序运行的目录(这里是当前目录-点)
主要程序:
with open('log.log') as f: log_list = f.readlines()
1、打包文件夹方式
pyinstaller --add-data "log.log;." log.py
ps:即可正常使用
2、打包单文件方式
pyinstaller -F --add-data "log.log;." log.py
ps:不能正常使用,原因是单文件打包的工作目录在 C:\Users\Administrator\AppData\Local\Temp\_MEIxxx下
解决方法1:程序不动,在打包后的log.exe同级目录下加上log.log文件,但这样也就没了--add-data选项的意义
解决方式2:
import sys
if getattr(sys, 'frozen', False):
print u'打包后运行中' curr_path = sys.argv[0] file_path = curr_path + '\\log.log' else: print '打包前运行中' file_path = 'log.log' with open(file_path) as f: log_list = f.readlines()
# getattr是pyinstaller打包后加的属性,用来区分现在是什么时候运行
# 但单文件不好的是,对这里的log.log进行修改的话是没有意义的,因为每次程序启动,都会生成一个不同的TEMp下的工作目录,这种情况还是使用文件夹方式打包
# 这种情况也可以使用winRAR等压缩软件,进行打包,效果也能达到
FAQ
1、带上图标打包:
pyinstaller -F -i 图标路径 路径+文件
ps:多一个-i ,图标格式必须没改,以及在文件的前面
2、解决中文乱码问题
当exe使用cmd启动,cmd的编码格式是gbk格式,所以需要将格式最终转换为 gbk格式
在2.7里,设置格式为 utf-8,转成gbk ,需要 utf-8->unicode->gbk
加上代码即可:
中文.decode("utf-8").encode('gbk')
3、打包flask程序(蓝本组织结构)
若是单文件:
因为工作路径在C:\Users\Administrator\AppData\Local\Temp\_MEIxxx下
所以需要将staic,template目录复制进,或使用--add-data选项,
但文件,数据库等修改没有意义!!
文件夹:
按原来的结构组织即可
ps:在这个过程遇到flask_apshceduler无法正常工作,提示
APScheduler: LookupError: No trigger by the name “date/cron/intervel” was found
问题关键:将添加任务的方式进行改变,
from apscheduler.triggers.date import DateTrigger
from apscheduler.triggers.cron import CronTrigger
trigger = DateTrigger(run_date=time) scheduler.add_job(func=task_socket, trigger=trigger, id=id, args=(ip_port, device_excute, device_name), ) trigger = CronTrigger(hour=hour,minute=minute, second=second) scheduler.add_job(func=task_socket, trigger=trigger, id=id, args=(ip_port, device_excute, device_name), )