# Python是解释型语言,我们写的Flask或Django项目如果部署,
# 源码可能会泄露,因此我们可以把项目打包成exe,来保护源码
# 需要用到工具
-pyinstaller:把python项目打包成不同平台的可执行文件
-nsis:NSIS(Nullsoft Scriptable Install System)是一个开源的 Windows 系统下
安装程序制作程序,它提供了安装、卸载、系统设置、文件解压缩等功能。
这如其名字所指出的那样,NSIS 是通过它的脚本语言来描述安装程序的行为和逻辑的
pip install pyinstaller
# 1 假设项目的启动文件是 run.py
# 2 pyinstaller -D run.py 打包项目文件
# 3 可以看到项目路径下 多了:
build文件夹 用于构建可执行文件
dist文件夹 包含应用程序的所有依赖项和可执行文件
run.spec 配置文件
# 4 如果项目代码里面涉及到一些不是.py文件(比如静态文件),但是项目里面又用到了这些静态文件
# pyinstaller模块是无法打包 这些非.py文件的!!!
那么你直接打包命令执行后,运行run.exe 是会有问题的, 打包的二进制文件里,会找不到该静态文件的
# 5 要把run.spec配置文件修改一下才行 然后再运行 pyinstaller .\run.spec 重新打包
datas=[('templates/index.html', 'templates'), ('static/style.css', 'static')],
datas=[('config.json', '.')],
# 元祖里第一个元素代表你希望在打包时包含的数据文件名称,该文件放到哪个目录下
# 打包完就可以看到dist/_internal/目录下有了对应的静态文件了!!!
# 就是把对应的 非py文件,也放到 dist/_internal/目录下
# 这样当二进制的run.exe运行时,就能找到这些非py文件了
可选参数 | 示例 | 说明 |
---|---|---|
-F | pyinstaller -F run.py | 只在dist文件夹中生成一个程序run.exe文件,适用于没有多依赖.py文件 |
-D | pyinstaller -D run.py | 默认选项,除了主程序run.exe外,还会在在dist文件夹中生成很多依赖文件,推荐使用这个,不容易出报错 |
-i | pyinstaller -i D:\demo.ico run.py | 给生成的demo.exe文件设置一个自定义的图标 |
项目中如果有些.py文件不想打包,比如配置文件,方便后续修改,怎么办
项目的启动文件run.py打包后,会在项目根目录下生成一个run.spec配置文件
# 然后在Analysis里面,datas对应写好对应的 非.py文件(比如一些静态文件)
pyinstaller .\run.spec # 重新打包
这样在 dist/_internal/目录下就可以看到,该不想打包的非.py文件
这样再次双击运行该run.exe python项目就起来了
# 想改配置,就直接在不想打包的非.py文件里改好保存,重启run.exe,新配置就生效了!!!
a = Analysis(['run.py'],
pathex=['D:\\sjy_repos\\ceshi'],
binaries=[],
datas=[('templates/index.html', 'templates'), ('static/style.css', 'static')],
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)
-------------------------------------------
# 如果是项目用的 settings.py 文件 ,我也不想被打包怎么办?
# 很简单,打包的时候,把settings.py挪到其他地方去,别放在当前项目里,等打完包后,
# 再把该settings.py粘贴到 dist/_internal/目录下
# 这样改 dist/_internal/settings.py 里的配置内容, 然后重启run.py 也能起作用了!!!
或者把配置文件内容不要写在settings.py,写到settings.json里面
run.spec配置文件改下
datas=[('settings.json','.')],
# 然后在启动文件里,读出该配置文件里面的数据, 去做赋值给对应的变量
# 还是改dist/_internal/ settings.json 然后保存后 重新启动run.py 新配置也能生效
# run.exe文件就不需要改了!!!
------------------------------------------------------
from gevent import monkey
monkey.patch_all()
import json
import os
from app_flask import app
from utils.uwsgi_server.server_gevent import *
if __name__ == "__main__": # 读取平台基本配置
if os.path.exists(file_path):
with open('./settings.json','r',encoding='utf-8') as setting_file:
settings_dict = json.load(setting_file)
SYS_NAME = settings_dict['SYS_NAME']
PORT = settings_dict['SERVICE_SERVER_PORT']
print("配置文件读取正确")
print(f'{SYS_NAME}[服务器模式]启动……')
server = uwsgi_server(app=app,address='0.0.0.0',port=PORT)
server.start()
打包后,运行.exe文件,报错说找不到setings文件等
# 有时候可能需要在启动文件里面加下面两行代码
import os, sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
# print(os.path.dirname(os.path.abspath(__file__)))
# print(sys.path)
# 有些地方可能反射字符串的操作,会和打包操作起冲突!!!
# 建议在虚拟环境下打包文件,而且建议在pip里面只安装项目能启动所必须得模块,无关的不要装
deactivate
python38 -m virtualenv venv # 根目录下创建venv虚拟环境文件夹
venv/scripts/activate
pip list
pyinstaller -D .\run.py # 打包run.py文件
flask项目打包过程中,报错解决
# Invalid async_mode specified
python install gevent
python install gevent-websocket
在flask的执行入口文件(app.py)中引入gevent,引入即可
from engineio.async_drivers import gevent
---------------------------------------
from flask import Flask, render_template
from flask_socketio import SocketIO, send, emit
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret_key'
socketio = SocketIO(app, async_mode='gevent')
# async_mode=用的是啥gevent,点到对应的gevent源码里面,
# 看执行该功能的时候,导入的是什么模块,可能需要提前在flask的执行入口文件中引入要需要的模块
# 应该就可以了!!!
标签:指南,文件,run,settings,python,py,__,打包
From: https://www.cnblogs.com/tengyifan888/p/18530689