python程序打包成exe文件

Posted on 2017-07-14 13:00  dyzne  阅读(801)  评论(0编辑  收藏  举报

今天试了试将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  ,图标格式必须没改,以及在文件的前面

制作ico图标链接

 

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), )