Python实战社群

Java实战社群

长按识别下方二维码,按需求添加

扫码关注添加客服

进Python社群▲

扫码关注添加客服

进Java社群

作者丨王翔丨

来源丨清风Python(ID:BreezePython)

python打包exe工具

Python打包工具主要有三种:py2exe、PyInstaller和cx_Freeze。虽然是三种工具,但是实现打包的方式都是大同小异。无非将Python运行所需的基础dll文件和源码依赖的模块筛选后聚合在一起,从而达到脱离环境单独运行的目的。但其中比较新奇的是它们居然可以将最终代码打包成单个文件去运行,简直不要太神奇。清风常用的打包工具为pyinstaller,安装下载简单,网上的文档也很齐全。

打包的exe如何执行

但凡大家看到python打包exe工具的优势,都会提到一句**打包成单个文件,可以保护源码不外泄。**对于新手来说,这个理由完美,单个文件怎么操作感觉也不会获得源码,但我只能说,天真啊!pyinstaller的官方文档:pyinstaller.readthedocs.io:How the One-File Program Works中有相关内容的详细说明,为了方便,我简单翻译下:

引导加载程序也是单文件捆绑包的核心。启动后,它将在此操作系统的相应临时文件夹位置中创建一个临时文件夹。该文件夹名为_MEIxxxxxx其中xxxxxx是一个随机数。一个可执行文件包含脚本使用的所有Python模块的嵌入式归档,以及任何非Python支持文件(例如,.so文件)的压缩副本。引导加载程序解压缩支持文件,并将副本写入临时文件夹。这可能需要一些时间。这就是为什么单文件应用程序比单文件夹应用程序启动慢的原因。

所以单个的exe文件在执行时,会先在系统临时目录下创建一个_MEI开头的文件夹,然后解压源码、依赖文件后,运行该临时文件夹下的内容。其中windows的临时文件夹通常为:

C:\Windows\Temp_MEIxxxx 或 

C:\Users\用户名\AppData\Local\Temp_MEIxxxx

但经过多次测试,几乎全在后者的目录下。其实只要在cmd下输入echo %temp% 或者 %tmp%就能确定了...

Linux的临时文件夹目录自然是在: /tmp/_MEIxxxxx 

当然,如果每次exe执行时,都会创建临时文件夹,但执行完成后又不销毁,岂不是早就导致我们的电脑磁盘空间溢出了。所以官方是有说明的:

创建临时文件夹后,引导程序将在临时文件夹的上下文中继续与单文件夹捆绑软件一样进行。当捆绑的代码终止时,引导加载程序将删除临时文件夹。如果程序崩溃或被杀死,则不会删除该文件夹(在Unix上为kill -9,在Windows上为Task Manager杀死,在Mac OS上为“ Force Quit”)。因此,如果您的应用程序频繁崩溃,则用户将丢失磁盘空间到多个临时文件夹。_MEIxxxxxx_MEIxxxxxx

打包Flask项目

pyinstalelr的基础使用就不在这里过多介绍了,之前的文章有过详细的说明:Python打包工具--Pyinstaller详细介绍:https://mp.weixin.qq.com/s/smsO0n8M18J7ofoOsWEjoQ

我们只需要知道pyinstaller -F(onefile)参数即可将代码最终打包为单个的exe文件即可。但是Flask的static、templates该怎么打包呢?让我们以之前开发过的一个FlaskHttpserver为例说明。首先看下代码结构:

settings中放了Flask的一些config配置,manage.py通过蓝图注册HttpServer中views下的account与home模块。那么,现在我们需要将代码中的static、templates、settings(测试发现这个配置文件也没办法自动打包,需要手动追加)成单个文件呢?pyinstaller提供了一个

[--add-data <SRC;DEST or SRC:DEST>]

的参数,整体打包命令如下:

 pyinstaller -F -i BreezePython.ico --add-data="HttpServer\static;HttpServer\static" --add-data="HttpServer\templates;Httpserver\templates" --add-data="settings.py;." manage.py

原理就是保持代码中的路径一致,如果是当前路径使用.进行替换。有些人觉得这个一个一个的添加太麻烦了,那么还有另一种思路。来看看我们打包后的目录:

打包完成后,会生成一个main应用.spec的文件,通过我们刚才一顿--add-data的操作后,spec有什么区别么?

所以我们可以换另一种方式加载依赖文件:

  1. 首次打包时直接-F 完成打包

  2. 编辑*.spec文件,通过在列表中添加对应元祖信息的方式,追加以来稳健

  3. pyinstaller -F *.spec进行二次打包即可追加文件至exe中。

来让我们看看打包后的exe是否可以执行吧:

OK,一个exe文件拉起整个Flask项目,带着exe我们就可以脱离环境单独运行我们的HTTPServer了。是不是很炫酷?

临时文件监控复制

初次测试,可能存在打包路径错误的问题,每次去找临时路径查看太麻烦了,既然写代码,不如顺手写个动态监控_MEI路径并完成循环复制的功能,具体实现如下:

  1. 判断电脑的操作系统

  2. while循环监控临时目录

  3. 启动exe工具

  4. 获取exe创建的_MEI开头文件夹

  5. 将该临时文件夹拷贝到执行目录

最终代码实现如下:

# -*- coding: utf-8 -*-
# @Author   : 王翔
# @微信号   : King_Uranus
# @公众号    : 清风Python
# @GitHub   : https://github.com/BreezePython
# @Date     : 2020/11/17 23:50:09
# @Software : PyCharm
# @version  :Python 3.7.3
# @File     : get_source_code.pyimport platform
import os
import time
import shutildef get_tmp_path():if platform.platform().lower().startswith('windows'):return os.getenv('temp')else:return '/tmp'class GetSourceCode:def __init__(self):self.base_path = os.path.dirname(__file__)self.tmp_path = get_tmp_path()self.basic_dirs = self.get_dirs()self.code_dir = Nonedef get_dirs(self):for root, dirs, files in os.walk(self.tmp_path):return set(dirs)def get_source_dir(self):while True:_dir = list(self.get_dirs() - self.basic_dirs)if _dir and _dir[0].startswith('_MEI'):self.code_dir = _dir[0]print("find source code dir %s" % self.code_dir)breakelse:time.sleep(0.2)self.copy_code_dir()def copy_code_dir(self):abs_tmp_path = os.path.join(self.tmp_path, self.code_dir)while os.path.exists(abs_tmp_path):source_path = os.path.join(self.base_path, self.code_dir)if not os.path.exists(source_path):os.mkdir(source_path)for root, dirs, files in os.walk(abs_tmp_path):for file in files:remote_path = root.replace(abs_tmp_path, source_path).replace('\\', '/')if not os.path.exists(remote_path):print(remote_path)os.makedirs(remote_path)if not os.path.exists(remote_path + '/' + file):shutil.copy(os.path.join(root, file), remote_path)print("Get source code end.")if __name__ == '__main__':print("start Source Code Analyse project.")print("Monitoring source files...")g = GetSourceCode()g.get_source_dir()

看看效果如何:

ok,快把你积攒已久的代码筛选下,看看那些适合打包成exe,拿去给朋友们炫耀吧!关于FlaskHttpserver,如果需要的朋友可以后台回复 服务 进行下载。

看到这里还不关注、点赞、转发下?听说这样三连操作,写代码没BUG哦!

程序员专栏 扫码关注填加客服 长按识别下方二维码进群

近期精彩内容推荐:  

 员工因上厕所时间超长被开除了

 程序员连续15天加班到凌晨2点在餐厅泪崩!

 还在try...catch?如果是那你就out了!

 Python很慢?Python之父一句话亮了

在看点这里好文分享给更多人↓↓

Flask项目能打包为单个exe文件运行?掌握原理后居然如此简单!相关推荐

  1. python总是提示缺少模块_python打包生成的exe文件运行时提示缺少模块的解决方法...

    事情是这样的我用打包命令:pyinstaller -F E:\python\clpicdownload\mypython.py打包了一个exe程序,但是运行时提示我缺 少bs4模块然后我就去查pyin ...

  2. python打包exe后缺少模块_python打包生成的exe文件运行时提示缺少模块的解决方法...

    python打包生成的exe文件运行时提示缺少模块的解决方法 事情是这样的我用打包命令:pyinstaller -F E:\python\clpicdownload\mypython.py打包了一个e ...

  3. JAVA项目的打包及生成.exe文件或者打包安装软件

    总体思路是先打成jar再把jar打成exe.主要看1.3和2.3里的内容就可以了. 1.将项目打成jar: 1.1要将项目打包成jar文件,方法很多,可以用Eclipse自带的打包工具Ant打包,也可 ...

  4. PyInstall的安装,使用,以及最后打包成一个exe文件

    首先PyInstall安装 pip3 install pyinstaller -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirro ...

  5. 将 C# .NET ( Core Framework ) WPF Winform 项目打包成单个 exe 可执行文件

    对于一个项目来说,如果能够把软件打包成单个 exe 可执行文件,无需安装,下载后直接打开即可使用,就可以极大地方便用户使用,从而增加用户使用你的产品的意愿.同时,依托于 .NET 的原生优势,一般大小 ...

  6. 使用Python第三方库xlwings将单个excel工作表快速拆分为多个工作表(附打包好的exe文件)

    使用Python第三方库xlwings将单个excel工作表快速拆分为多个工作表(附打包好的exe文件) 资源链接 CSDN:https://download.csdn.net/download/qq ...

  7. 在.NET Core 3.0中发布单个Exe文件(PublishSingleFile)

    假设我有一个简单的" Hello World"控制台应用程序,我想发送给朋友来运行.朋友没有安装.NET Core,所以我知道我需要为他构建一个独立的应用程序.很简单,我只需在项目 ...

  8. C# 控制台程序的开发和打包为一个exe文件

    目录 前言 一.我的第一个C#控制台程序 二.发布为一个exe文件 前言 本文通过C#编写一个简单的示例计算器,来演示C#的使用和使用 Visual Studio 打包为一个 exe 文件. 一.我的 ...

  9. exe4j打包jar成exe文件(将jdk打包在内)

    用myEclipse -> Export 生成.class文件,然后再用 exe4j 打包工具选择刚导出的 .class 文件 之前用exe4j打包有过示例,按照之前的博客文档http://bl ...

最新文章

  1. TMG 日志队列(Log Queue,扩展名为 .LLQ)持续增长或 TMG
  2. 一种通过U盘热插拔的升级方法
  3. Android华容道之一步一步实现-6-还原状态检测
  4. 函数计算自动化运维实战 3 -- 事件触发自动创建快照
  5. 软中断amp;taskletamp;工作队列
  6. c语言模拟java面向对象_纯c语言实现面向对象分析与示例分享
  7. [html] 写页面布局时你有考虑过分辨率因素吗?还要考虑哪些因素呢
  8. OpenCV-python学习笔记(二)——image processing图像基本处理
  9. 开源 Android pdf 阅读器开发总结
  10. sh与bash中的export语法的区别
  11. grads插值_Grads画等值线(一)-----心得感言
  12. 为什么要创建SRT?
  13. 蔡氏电路matlab仿真实代码验,基于蔡氏电路的MATLAB仿真
  14. visio画等分树状图
  15. 快慢指针之练习【2】
  16. 个人随笔-求学求职-工作经历-计划
  17. HTML基础笔记笔记
  18. 高中计算机学校分数线,高中职校录取分数线
  19. 运行引擎需要d3d11兼容GPU,如何解决
  20. 制作一台计算机需要多少知识,如何制造一台计算机,编程多年后我开始思考这个问题...

热门文章

  1. Cell Reports : 人脑中的湍流状动力学
  2. 格力(GREE)家用移动空调免安装一体机空调KY-23NK 清灰拆装教程
  3. 【Day3.4】东台吉尔湖
  4. 在Mac中使用Mounty for NTFS向移动硬盘备份文件
  5. Python之第六章 内置容器 --- 字符串
  6. 一文搞懂什么是PWM!
  7. 微信中域名网站域名被封锁、被屏蔽、被和谐后的解决方法
  8. 【pytorch torchvision源码解读系列—1】Alexnet
  9. 怪异的JavaScript系列(一)
  10. _混沌系统的FPGA实现