将python项目(django/flask)打包成exe和安装包

您所在的位置:网站首页 python安装程序包 将python项目(django/flask)打包成exe和安装包

将python项目(django/flask)打包成exe和安装包

2023-07-28 18:37| 来源: 网络整理| 查看: 265

目录 打包Flask项目写一个简单的Flask项目下载pyinstaller进入到项目路径下,执行运行exe,测试 使用nsis把文件夹打包成windows的安装包下载安装nsis把dist文件夹下的run文件夹压缩成zip使用nsis把压缩包,做成windows安装文件 打包Django项目写一个简单的django项目,准备静态文件使用 pyinstaller打包执行打包成的exe把templates和static文件夹copy到dist/manage文件夹下运行项目注意一些坑 打包其他项目(小工具)准备一个多文件的小工具源码执行打包程序生成.spec配置文件修改.spec配置文件重新打包 .spec脚本参数介绍其他打包工具(cx_Freeze,PyOxidizer,Py2exe,Briefcase)pyinstallercx_FreezePyOxidizerPy2exe Q&A打包过程找不到自己自建模块.spec文件Analysis OptionsBuild OptionsDeployment Options 一个应用有多个文件夹要如何打包成一个exe且不要多余的依赖文件

Python是解释型语言,Flask或Django项目如果部署,源码可能会泄露,因此可以把项目打包成exe,来保护源码。需要用到的工具: pyinstaller:把python项目打包成不同平台的可执行文件nsis:NSIS(Nullsoft Scriptable Install System)是一个开源的 Windows 系统下安装程序制作程序,它提供了安装、卸载、系统设置、文件解压缩等功能。这如其名字所指出的那样,NSIS 是通过它的脚本语言来描述安装程序的行为和逻辑的 打包Flask项目 写一个简单的Flask项目

在这里插入图片描述

下载pyinstaller pip install pyinstaller 可选参数示例说明-Fpyinstaller -F demo.py只在dist文件夹中生成一个程序demo.exe文件,适用于一个模块没有多依赖.py文件-Dpyinstaller -D demo.py默认选项,除了主程序demo.exe外,还会在在dist文件夹中生成很多依赖文件,推荐使用这个-cpyinstaller -c demo.py默认选项,只对windows有效,使用控制台-wpyinstaller -w demo.py只对windows有效,不使用控制台-ppyinstaller -p D:\project\demo.py设置导入路径-ipyinstaller -i D:\demo.ico demo.py给生成的demo.exe文件设置一个自定义的图标 进入到项目路径下,执行 # run.py 是flask项目的执行文件,app.run所在py文件 pyinstaller -D run.py # 可以看到项目路径下有 -build文件夹 -dist文件夹:重要,下有run文件夹(py文件名字),有个run.exe(py文件的名字) -run.spec # 把pro_flask这个文件夹,拷贝到dist下的run文件夹 -因为flask项目有静态文件和html文件,如果不拷贝过去,静态文件和html文件会找不到 -我们为了隐藏代码,可以把所有python的代码都删除,只留static和templates文件夹

在这里插入图片描述

运行exe,测试 # 到dist/run文件夹下,双击 run.exe,启动 # 浏览器访问

在这里插入图片描述

使用nsis把文件夹打包成windows的安装包 下载安装nsis nsis:NSIS(Nullsoft Scriptable Install System)是一个开源的 Windows 系统下安装程序制作程序,它提供了安装、卸载、系统设置、文件解压缩等功能。这如其名字所指出的那样,NSIS 是通过它的脚本语言来描述安装程序的行为和逻辑的 利用 nsis 把刚刚的dist的run文件夹打包成windows的安装包

在这里插入图片描述

把dist文件夹下的run文件夹压缩成zip

在这里插入图片描述

使用nsis把压缩包,做成windows安装文件

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

打包Django项目 写一个简单的django项目,准备静态文件 # 在django项目的配置文件中修改settings.py STATIC_ROOT = os.path.join(BASE_DIR, 'static', 'static_root') # 修改urls.py from django.conf.urls import static from django.conf import settings urlpatterns = [ path('admin/', admin.site.urls), path('', views.index), ] urlpatterns += static.static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) # 执行 静态文件收集 python manage.py collectstatic # 会把所有静态文件收集到项目的static路径下的static_root文件夹下 使用 pyinstaller打包 # 进入到项目路径下 pyinstaller -D manage.py # 生成dist文件夹,build文件夹和manage.spec文件 执行打包成的exe # 此时在项目路径下会生成dist文件夹,内部manage文件夹下有manage.exe manage.exe runserver # 运行服务是会提示No module named XXX 执行会报错,提升缺少模块,我的提示少app01.apps ######### 这是因为Django有些module不会自动收集,需要手动添加 解决方法:在manage.spec文件中修改hiddenimports=[]为hiddenimports=['app01.apps','users.apps',],提示缺少什么module就在此处添加什么。 ######### 修改manage.spec,hiddenimports=['app01.apps',] # 再重新编译一下,运行 pyinstaller manage.spec 把templates和static文件夹copy到dist/manage文件夹下 运行项目 manage.exe runserver 0.0.0.0:8080 注意一些坑 # 问题1:运行服务提示No module named XXX 这是因为Django有些module不会自动收集,需要手动添加 解决方法:在manage.spec文件中修改hiddenimports=[]为hiddenimports=['users','users.apps',],提示缺少什么module就在此处添加什么。 # 问题2:打开网页出现TemplateDoesNotExist 错误 解决方法:把项目中的模板文件templates拷贝到dist下的manage文件夹,刷新页面即可。 # 问题3:静态文件找不到 1、首先在项目中的settings文件中添加如下代码,其中static是项目中的静态文件位置,static_root是static下的一个空文件夹,然后执行python manage.py collectstatic命令将静态文件收录到static_root中 STATIC_ROOT = os.path.join(BASE_DIR, 'static', 'static_root') 2、然后在urls.py中添加如下代码: from django.conf.urls import static from project_1 import settings urlpatterns += static.static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) 打包其他项目(小工具) 准备一个多文件的小工具源码

在这里插入图片描述 注意路径处理,使用__file___的地方,需要改成"./",否则目录会创建到AppData的临时目录中,AppData是windows规定给软件倒垃圾的地方,但这与需求不符合。

# 目录 input_excel_folder = os.path.join("./", "in", "excel") input_word_folder = os.path.join("./", "in", "word") # 模板目录 template_folder = os.path.join("./template") # 文件输出目录 out_folder = os.path.join("./", "out") # 临时目录 tmp_folder = os.path.join("./", "out", "tmp") 执行打包程序生成.spec配置文件

pyinstaller -F main.py

修改.spec配置文件

执行main.exe文件,提示缺少什么就在spec中加什么。

a = Analysis( ['main.py'], pathex=[], binaries=[], # 我的项目导入了runner,interface文件夹下面的包,需要在此处添加 datas=[("runner/*","runner"),("interface/*","interface")], # 我的项目导入了第三方包,需要在此添加 hiddenimports=["runner","docx","docxtpl","xlrd","tkinter","jinja2","matplotlib"], hookspath=[], hooksconfig={}, runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False, ) 重新打包

pyinstaller main.spec

最终生成的包大小为: 在这里插入图片描述 将exe文件和模板文件单独放到一个文件夹,此时已经可以正常使用。(打印help乱码不影响使用) 在这里插入图片描述

.spec脚本参数介绍 # -*- mode: python ; coding: utf-8 -*- block_cipher = None a = Analysis( ['main.py'], pathex=[], binaries=[], datas=[], hiddenimports=[], hookspath=[], hooksconfig={}, runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False, ) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE( pyz, a.scripts, [], exclude_binaries=True, name='main', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, console=True, disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, ) coll = COLLECT( exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, upx_exclude=[], name='main', )

生成的脚本就是这样的,包含以下主要配置参数:

参数含义aAnalysis类的实例,主要分析.py文件的依赖项,如第三方库以及import模块。a中内容主要包括以下四部分:scripts,放入.py文件。;pure,程序代码文件中的纯Python模块,包括程序的代码文件本身;binaries,需要的二进制文件。;datas,非二进制文件。pyzPYZ的实例,是一个.pyz文件,包含了所有pure中的所有Python模块。exeEXE类的实例,处理Analysis和PYZ的结果的,用来生成最后的exe可执行程序。collCOLLECT类的实例,用于创建输出目录。只有-D命令下才会实例化,-F不会生成目录。block_cipher加密密钥(一般无加密需求,可不设置)

而我们一般在配置时大多数情况下只涉及a,也就是Analysis类,下面逐一分析a里面的参数

Analysis的参数简介以及可能存在的问题scripts

首先是一个列表(list),应该存放与打包文件相关的所有.py文件。如果不存放的话会出现import错误 no module 的问题。

pathex

默认有一个spec的目录,记得把用到的模块的路径添加到这个list变量里。

默认的路径是你打包的.py文件的同级路径。

存在问题:当引入自己的文件时添加此路径并不起作用。仍会报错

ModuleNotFoundError: No module named 'core'

datas将资源文件或文件夹,复制到打包后的目录中,而datas中必须以元组形式否则会出现下面错误。注意一点放到这里面的文件不会被编译,而是复制,所以重要的文件放到这里很容易泄露。 ValueError: too many values to unpack (expected 2)

binaries   添加二进制文件,也是一个列表,定义方式与datas参数一样。hiddenimports隐式导入的模块,比如在__import__、imp.find_module()、exec、eval等语句中导入的模块,这些模块PyInstaller是找不到的,需要手动指定导入,hookspath指定额外hook文件(可以是py文件)的查找路径。runtime_hooks 指定自定义的运行时hook文件路径(可以是py文件)excludes 指定可以被忽略的可选的模块或包。 其他打包工具(cx_Freeze,PyOxidizer,Py2exe,Briefcase)

PyInstaller:PyInstaller 是一个流行的 Python 打包工具,可以将 Python 应用程序打包成单个可执行文件。PyInstaller 会自动识别和打包 Python 应用程序的所有依赖项,并支持多平台,包括 Windows、Linux 和 macOS。它使用 Python 语言编写,易于安装和使用。此外,PyInstaller 还提供了一些高级选项,如优化生成的可执行文件的大小和性能等。

cx_Freeze:cx_Freeze 是另一个流行的 Python 打包工具,可以将 Python 应用程序转换为可执行文件或打包成 ZIP 文件。与 PyInstaller 不同,cx_Freeze 可以生成 Windows、Linux 和 macOS 上的可执行文件。cx_Freeze 使用 Python 语言编写,易于安装和使用。它可以自动识别和打包 Python 应用程序的所有依赖项,并支持多个 Python 版本。

PyOxidizer:PyOxidizer 是一个新兴的 Python 打包工具,它使用 Rust 编写,旨在提供高度优化的可执行文件。PyOxidizer 具有良好的跨平台支持,并支持将 Python 代码打包成单个可执行文件或动态链接库。PyOxidizer 还提供了一些高级选项,如动态链接库预热、运行时优化等。PyOxidizer 不仅支持 Python 语言,还支持 Rust 和 C 语言。

Py2exe:Py2exe 是一个古老但仍然有用的 Python 打包工具,可以将 Python 应用程序转换为 Windows 可执行文件。Py2exe 可以自动识别和打包所有依赖项,并提供一些选项来优化生成的可执行文件的大小和性能。Py2exe 由于只支持 Windows 平台,因此在 Windows 上表现最佳。Py2exe 使用 Python 语言编写,易于安装和使用。

pyinstaller

优点:

PyInstaller 具有广泛的操作系统支持,可以在 Windows、Linux 和 macOS 上打包应用程序。PyInstaller 可以自动识别和打包 Python 应用程序的所有依赖项,从而减少了配置和管理的工作量。PyInstaller 可以生成单个可执行文件,这使得分发和安装 Python 应用程序变得简单和方便。PyInstaller 支持多个 Python 版本,并且易于安装和使用。PyInstaller 提供了许多选项,如优化生成的可执行文件的大小和性能等。

缺点:

生成的可执行文件的体积可能较大。在某些情况下,PyInstaller 可能无法识别 Python 应用程序的所有依赖项,从而导致运行时错误。需要在不同的操作系统上生成不同的可执行文件,这可能增加了开发和测试的工作量。 cx_Freeze

优点:

cx_Freeze 支持多个操作系统,包括 Windows、Linux 和 macOS。cx_Freeze 可以将 Python 应用程序转换为可执行文件或打包成 ZIP 文件,这使得分发和安装 Python 应用程序变得简单和方便。cx_Freeze 可以自动识别和打包 Python 应用程序的所有依赖项,从而减少了配置和管理的工作量。cx_Freeze 提供了许多选项,如优化生成的可执行文件的大小和性能等。cx_Freeze 支持多个 Python 版本,并且易于安装和使用。

缺点:

在某些情况下,cx_Freeze 可能无法识别 Python 应用程序的所有依赖项,从而导致运行时错误。生成的可执行文件可能较大。cx_Freeze 缺少对一些高级功能的支持,如动态链接库预热和运行时优化等。 PyOxidizer

优点:

PyOxidizer 提供了高度优化的可执行文件,这使得生成的应用程序在性能和体积方面表现优异。PyOxidizer 具有良好的跨平台支持,支持将 Python 代码打包成单个可执行文件或动态链接库。PyOxidizer 提供了一些高级选项,如动态链接库预热和运行时优化等。PyOxidizer 不仅支持 Python 语言,还支持 Rust 和 C 语言。PyOxidizer 可以自动识别和打包 Python 应用程序的依赖项,从而减少了配置和管理的工作量。

缺点:

PyOxidizer 只支持 Python 3.6 或更高版本,不支持 Python 2.x。PyOxidizer 的配置比较复杂,需要使用 Rust 编程语言进行构建和配置。PyOxidizer 缺少一些常见的选项,如生成调试符号和管理包含资源的应用程序。 Py2exe

优点:

Py2exe 支持将 Python 应用程序转换为 Windows 上的可执行文件。Py2exe 可以自动识别和打包 Python 应用程序的所有依赖项,从而减少了配置和管理的工作量。Py2exe 支持多个 Python 版本,并且易于安装和使用。Py2exe 提供了一些高级选项,如优化生成的可执行文件的大小和性能等。

缺点:

Py2exe 只能在 Windows 上运行,并且只能将 Python 应用程序转换为 Windows 上的可执行文件。生成的可执行文件可能较大。Py2exe 缺少对一些高级功能的支持,如动态链接库预热和运行时优化等。 Q&A 打包过程找不到自己自建模块

ModuleNotFoundError: No module named 'core'

可以将模块添加到datas里注意复制后的名字(‘core’,‘core’)最好是原名(推荐)。

还可以将自己的模块直接复制到site-packages 下面,再打包(不推荐)。

.spec文件

.spec文件是PyInstaller的配置文件,它包含了构建可执行文件时的各种配置选项。在PyInstaller打包的过程中,可以手动编辑.spec文件以更改某些选项。

使用以下命令生成.spec文件: pyinstaller --name=myapp --onefile main.py 可以将–name选项替换为想要的应用程序名称,并将main.py替换为主脚本文件名。

Analysis Options

这一部分指定应用程序的入口点(通常是main.py文件),并包含一些其他配置选项,例如要添加的路径、要排除的模块等等。

a = Analysis(['main.py'], pathex=['/path/to/myapp'], binaries=[], datas=[], hiddenimports=[], hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False) Build Options

这一部分包含与构建可执行文件有关的选项,例如输出文件名、是否要创建调试版本等等。

exe = EXE(pyz, a.scripts, exclude_binaries=True, name='myapp', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, upx_exclude=[], upx_include=[], console=True ) Deployment Options

这一部分包含与部署可执行文件有关的选项,例如生成的可执行文件是否要包含所有必需的依赖项、是否要创建单个文件等等。

pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) 一个应用有多个文件夹要如何打包成一个exe且不要多余的依赖文件

打包多个文件夹成一个exe文件,可以将多个文件夹中的Python文件和资源文件都复制到同一个目录下,然后使用PyInstaller打包该目录。

以下是一个示例.spec文件,假设有两个文件夹runner和helper都需要打包。

# -*- mode: python ; coding: utf-8 -*- block_cipher = None a = Analysis(['main.py'], pathex=['path/to/main.py'], binaries=[], datas=[('runner/*', 'runner'), ('helper/*', 'helper')], hiddenimports=[], hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE(pyz, a.scripts, exclude_binaries=True, name='myapp', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, upx_exclude=[], runtime_tmpdir=None, console=True )

其中,datas参数指定了需要打包的文件夹及其对应的在exe文件中的路径,(‘runner/', ‘runner’)表示将runner文件夹下的所有文件打包,并在exe文件中创建runner文件夹。同理,('helper/’, ‘helper’)表示将helper文件夹下的所有文件打包,并在exe文件中创建helper文件夹。

使用命令pyinstaller yourapp.spec即可打包应用,并且不会有多余的依赖文件。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3