web应用程序有哪些 web应用程序开发 python web实例教程

本教程旨在解决在python web应用中集成交互式地图与后端计算逻辑的挑战。我们将探讨为何直接结合`folium`与基于`input()`的python函数难以实现复杂的web交互,并提供两种主要解决方案:一是利用streamlit或gradio等python-only ui框架快速构建原型,二是采用flask/fastapi作为后端与javascript前端(如leaflet.js)构建功能完善的web应用。文章将详细阐述各方案的实现思路、示例代码及关键注意事项,帮助开发者实现地图点击触发后端计算并获取用户输入的需求。
理解交互式地图与后端逻辑集成的挑战在Web应用开发中,将前端的用户交互(如地图点击)与后端的业务逻辑(如计算器)紧密结合是一个常见需求。然而,直接将Python的folium库生成的静态HTML地图与包含input()函数进行用户输入的Python脚本结合,在Web环境中是行不通的。
folium的局限性: folium是一个强大的Python库,用于生成基于Leaflet.js的交互式地图HTML文件。它主要侧重于地图数据的可视化,并允许通过Popup添加静态或简单的动态内容。然而,folium本身并不提供与Python后端进行实时、复杂交互的机制,例如在点击地图区域后直接在Python后端触发一个需要用户输入的操作。它生成的HTML是客户端页面,其上的JavaScript代码默认无法直接调用服务器端的Python函数。
input()函数的局限性: Python的input()函数用于从控制台获取用户输入,它是一个阻塞式操作,仅适用于命令行环境。在Web应用中,用户输入是通过浏览器界面(HTML表单、JavaScript提示框等)进行的,而不是通过服务器的控制台。因此,将包含input()的Python函数直接用于Web后端处理用户请求是不合适的。
为了实现地图点击触发后端计算并获取用户输入的目标,我们需要采用更适合Web应用开发的架构和工具。以下是两种主要的方法:
立即学习“Python免费学习笔记(深入)”;
方案一:利用Python-only UI框架快速构建交互应用对于需要快速原型开发或偏好纯Python环境的场景,Streamlit和Gradio等框架提供了极佳的解决方案。它们抽象了Web开发的复杂性,让开发者能用纯Python代码构建交互式Web应用。
1. StreamlitStreamlit是一个用于创建数据应用的开源框架。它提供了一系列组件,包括地图、输入框、按钮等,可以轻松地将数据科学模型和交互式界面结合起来。
实现思路:
使用Streamlit的地图组件(如st.map或结合pydeck)展示地理数据。通过Streamlit的输入组件(如st.number_input)获取用户输入的“需求”和“投资”值。将地图点击事件(如果Streamlit的地图组件支持)或通过选择框、滑块等方式选择地区,然后将地区信息和用户输入传递给后端计算函数。示例代码(概念性):
import streamlit as stimport pandas as pdimport geopandas as gpdimport pulp # 假设 lp 函数已修改为接受参数# 假设 consts 函数已修改为接受 district_name 并返回 A, B, Cdef consts(district_name): # 模拟从Excel读取数据 data = { "District A": {"A": 10, "B": 20, "C": 30}, "District B": {"A": 15, "B": 25, "C": 35}, # ... 更多地区数据 } return data.get(district_name, {"A": 0, "B": 0, "C": 0})def lp_solver(district_name, demand, investment): # 原始 lp 函数的修改版本,不再使用 input() import pulp model = pulp.LpProblem(name="Lp", sense=pulp.const.LpMinimize) # 获取地区常数 district_consts = consts(district_name) A = float(district_consts.get("A")) B = float(district_consts.get("B")) C = float(district_consts.get("C")) x_1 = pulp.LpVariable(name="x_1", lowBound=0) x_2 = pulp.LpVariable(name="x_2", lowBound=0) x_3 = pulp.LpVariable(name="x_3", lowBound=0) obj_func = 41*x_1 + 11*x_2 + 24*x_3 model += obj_func model += (x_1 + x_2 + x_3 >= demand) model += (A*x_1 + B*x_2 + C*x_3 <= investment) status = model.solve() results = {} if status == pulp.LpStatusOptimal: for var in model.variables(): results[var.name] = var.value() else: results["status"] = pulp.LpStatus[status] return resultsst.title("莫桑比克地区投资优化器")# 加载地理数据 (Streamlit的st.map可能需要DataFrame,或者使用st.pydeck_chart)# 这里假设我们有一个包含地区名称和坐标的DataFrame# 实际应用中,你需要将GeoDataFrame转换为适合Streamlit地图组件的格式# 例如,如果使用st.map,需要有'lat'和'lon'列# df_districts = pd.DataFrame({# 'district': ['District A', 'District B'],# 'lat': [-18.6, -19.0],# 'lon': [35.5, 36.0]# })# st.map(df_districts)# 或者,更常见的是使用下拉选择框来模拟地图点击选择地区# 假设你从GeoDataFrame中提取了地区列表# folder_path = r'D:\Trabalho de Licenciatura\New folder\Python\Moz Geo Data\Distritos'# shapefile_path = folder_path + "\Distritos.shp"# districts_gdf = gpd.read_file(shapefile_path)# district_names = districts_gdf['ADM2_PT'].tolist() # 假设 'ADM2_PT' 是地区名称district_names = ["District A", "District B", "District C"] # 示例地区名称selected_district = st.selectbox("选择一个地区:", district_names)st.subheader(f"为 {selected_district} 输入参数:")demand = st.number_input("输入需求 (Demand):", min_value=0.0, value=100.0)investment = st.number_input("输入投资 (Investment):", min_value=0.0, value=500.0)if st.button("运行优化"): if selected_district: with st.spinner('正在计算...'): results = lp_solver(selected_district, demand, investment) st.success("计算完成!") st.write("### 优化结果:") for var_name, value in results.items(): st.write(f"{var_name}: {value:.2f}") else: st.warning("请先选择一个地区。")登录后复制优点:
纯Python开发,无需JavaScript知识。开发速度快,适合快速原型和内部工具。内置丰富的UI组件。缺点:
AppMall应用商店 AI应用商店,提供即时交付、按需付费的人工智能应用服务
56 查看详情
对前端的控制力相对较弱,定制化程度有限。地图组件的交互性可能不如专业的JavaScript地图库。部署可能需要特定的Streamlit服务器。2. GradioGradio是另一个用于快速构建机器学习模型Web界面的Python库。它也支持各种输入和输出组件,包括图像、文本和数字。
实现思路:与Streamlit类似,Gradio也提供组件来构建界面。它有一个gr.Plot组件可以用于展示地图,但更常见的用法是结合下拉框或文本输入来选择地区,然后获取用户输入。
示例代码(概念性):
import gradio as grimport pulp# 假设 consts 函数已修改def consts(district_name): data = { "District A": {"A": 10, "B": 20, "C": 30}, "District B": {"A": 15, "B": 25, "C": 35}, } return data.get(district_name, {"A": 0, "B": 0, "C": 0})def lp_solver_gradio(district_name, demand, investment): # 原始 lp 函数的修改版本 import pulp model = pulp.LpProblem(name="Lp", sense=pulp.const.LpMinimize) district_consts = consts(district_name) A = float(district_consts.get("A")) B = float(district_consts.get("B")) C = float(district_consts.get("C")) x_1 = pulp.LpVariable(name="x_1", lowBound=0) x_2 = pulp.LpVariable(name="x_2", lowBound=0) x_3 = pulp.LpVariable(name="x_3", lowBound=0) obj_func = 41*x_1 + 11*x_2 + 24*x_3 model += obj_func model += (x_1 + x_2 + x_3 >= demand) model += (A*x_1 + B*x_2 + C*x_3 <= investment) status = model.solve() output_str = "" if status == pulp.LpStatusOptimal: output_str += "### 优化结果:\n" for var in model.variables(): output_str += f"{var.name}: {var.value():.2f}\n" else: output_str += f"优化状态: {pulp.LpStatus[status]}\n" return output_str# 假设你从GeoDataFrame中提取了地区列表district_names = ["District A", "District B", "District C"]iface = gr.Interface( fn=lp_solver_gradio, inputs=[ gr.Dropdown(district_names, label="选择地区"), gr.Number(label="需求 (Demand)", value=100.0), gr.Number(label="投资 (Investment)", value=500.0) ], outputs="markdown", # 输出为Markdown格式 title="莫桑比克地区投资优化器 (Gradio)", description="选择一个地区并输入需求和投资,然后运行线性规划优化。")iface.launch()登录后复制优点:
快速构建交互界面,特别适合机器学习演示。提供多种输入输出组件。缺点:
地图交互性不如专门的地图库。对于复杂的Web应用,功能可能受限。方案二:构建完整的Web应用(后端+前端)如果需要高度定制化的界面、更复杂的交互逻辑或生产级的Web应用,推荐使用传统的Web应用架构:Python后端框架(如Flask或FastAPI)处理业务逻辑和数据,配合JavaScript前端框架(如React、Vue、Angular)或纯JavaScript/HTML/CSS处理用户界面和交互。
1. 后端:Flask/FastAPIFlask和FastAPI是轻量级的Python Web框架,用于构建API服务和Web应用。它们负责接收前端请求、执行Python业务逻辑、与数据库交互,并返回数据给前端。
核心思想:
将lp和consts函数封装成API接口。前端通过HTTP请求(GET/POST)将地区、需求、投资等参数发送到后端。后端调用lp函数进行计算,并将结果通过JSON格式返回给前端。lp和consts函数的改造:这两个函数需要修改为接受参数而不是使用input()。
# consts 函数改造import openpyxldef get_district_constants(district_name): values = {} # 假设 Excel 文件路径固定 book = openpyxl.load_workbook(r"D:\Trabalho de Licenciatura\New folder\Python\WebApp\Dados_py.xlsx") worksheet = book["Dados"] for row in worksheet.iter_rows(min_row=1, values_only=True): if row[0] == district_name: values = { "A": float(row[1]), # 确保转换为浮点数 "B": float(row[2]), "C": float(row[3]) } break # 找到即停止 return values# lp 函数改造import pulpdef solve_lp(district_name, demand, investment): model = pulp.LpProblem(name="Lp", sense=pulp.const.LpMinimize) constants = get_district_constants(district_name) if not constants: return {"error": f"District '{district_name}' not found or constants missing."} A = constants["A"] B = constants["B"] C = constants["C"] x_1 = pulp.LpVariable(name="x_1", lowBound=0) x_2 = pulp.LpVariable(name="x_2", lowBound=0) x_3 = pulp.LpVariable(name="x_3", lowBound=0) obj_func = 41*x_1 + 11*x_2 + 24*x_3 model += obj_func model += (x_1 + x_2 + x_3 >= demand) model += (A*x_1 + B*x_2 + C*x_3 <= investment) status = model.solve() results = {"status": pulp.LpStatus[status]} if status == pulp.LpStatusOptimal: for var in model.variables(): results[var.name] = var.value() return results登录后复制Flask后端示例:
from flask import Flask, request, jsonify, render_templatefrom flask_cors import CORS # 处理跨域请求app = Flask(__name__)CORS(app) # 允许所有来源的跨域请求,生产环境请限制# 假设 get_district_constants 和 solve_lp 函数已定义在同一文件或导入# from .your_module import get_district_constants, solve_lp @app.route('/')def index(): # 返回一个包含地图和表单的HTML页面 # 可以在这里生成 folium 地图并嵌入到模板中 # 或者直接加载一个预先生成的 folium HTML 文件 # map_html = create_map_html() # 假设 create_map_html() 返回 folium 生成的HTML字符串 # return render_template('index.html', map_content=map_html) return render_template('index.html') # 假设 index.html 包含一个 div 用于加载地图@app.route('/calculate', methods=['POST'])def calculate(): data = request.get_json() # 获取前端发送的JSON数据 district = data.get('district') demand = data.get('demand') investment = data.get('investment') if not all([district, demand is not None, investment is not None]): return jsonify({"error": "Missing parameters"}), 400 try: demand = float(demand) investment = float(investment) result = solve_lp(district, demand, investment) return jsonify(result) except ValueError: return jsonify({"error": "Invalid demand or investment values"}), 400 except Exception as e: return jsonify({"error": str(e)}), 500if __name__ == '__main__': app.run(debug=True)登录后复制templates/index.html 示例:
<!DOCTYPE html><html><head> <title>莫桑比克地图优化器</title> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" /> <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script> <style> #map { height: 600px; width: 100%; } .popup-content { font-family: sans-serif; } .input-form { margin-top: 20px; padding: 15px; border: 1px solid #ccc; border-radius: 5px; } .result-display { margin-top: 20px; padding: 15px; border: 1px solid #eee; background-color: #f9f9f9; border-radius: 5px; } </style></head><body> <h1>莫桑比克地区投资优化</h1> <div id="map"></div> <div class="input-form" id="inputForm" style="display: none;"> <h2>为 <span id="selectedDistrictName"></span> 地区输入参数</h2> <label for="demand">需求 (Demand):</label> <input type="number" id="demand" value="100" step="0.1"><br><br> <label for="investment">投资 (Investment):</label> <input type="number" id="investment" value="500" step="0.1"><br><br> <button onclick="submitCalculation()">运行优化</button> </div> <div class="result-display" id="resultDisplay" style="display登录后复制以上就是Python Web应用中交互式地图与后端业务逻辑的集成指南的详细内容,更多请关注乐哥常识网其它相关文章!
相关标签: css vue react javascript excel python java html js 前端 Python JavaScript flask 架构 json css html angular 前端框架 fastapi 封装 接口 map JS 事件 input 数据库 http ui 应用开发 大家都在看: 使用 CSS Grid 创建动态可变尺寸的方格布局 动态创建响应式网格布局:从Flexbox到CSS Grid的优化实践 解决CSS悬停效果导致标签布局跳动:使用绝对定位优化用户体验 如何在Outlook中保留HTML/CSS生成的邮件签名样式 如何在Outlook 2016中保留HTML签名样式:内联CSS解决方案