news 2026/8/25 8:09:48

Python交互式Web框架:Streamlit、Gradio、Dash、Hyperdiv

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python交互式Web框架:Streamlit、Gradio、Dash、Hyperdiv

概述

本文搜集几个流行的后端友好、基于Python语言、交互式Web框架,可实现无需过多前端开发技能,几行代码实现一个MVP展示界面,可应用:数据可视化、原型快速开发、机器学习数据探索等诸多场景。

Streamlit

官网,开源(GitHub,41.4K Star,3.7K Fork),Python Web框架,可用极少代码快速搭建交互式Web数据应用,如数据分析、可视化展示等。提供在线体验地址Playground。

功能

  • 轻松创建Web应用:简化将Python脚本转为响应式网页的过程,只需几行代码,无需Flask、Django或前端经验
  • 数据处理与EDA:使用pandas和numpy等库导入和处理数据,进行探索性数据分析(EDA)以挖掘洞见
  • 动态可视化:内置图表能展示趋势和比较,配合交互式控件和美观的图表
  • 直观的用户控制:下拉菜单、滑块和侧边栏让用户能引导分析,为仪表板带来交互性

特点:

  • 不需要开发者拥有丰富的前端知识;
  • 包含丰富的数据展示形式;
  • 通过Python代码可控制应用程序的运行逻辑。

架构图

3个模块:

  • 数据展示;
  • 数据输入;
  • 流程和UI设置。

使用

安装:pip install streamlit

使用命令行工具,需配置环境变量。

importstreamlitasstimportpandasaspdimportnumpyasnpimportmatplotlib.pyplotasplt st.title('标题')st.header('')st.subheader('')st.text('')df=pd.DataFrame({'列1':[1,2,3],'列2':[4,5,6]})st.dataframe(df)x=np.linspace(0,10,100)y=np.sin(x)plt.plot(x,y)st.pyplot(plt)name=st.text_input('请输入名字')st.write(name)ifst.button('点击')st.write('好的')

输入streamlit run demo.py命令,浏览器打开http://localhost:8501体验吧。

部署需要到官网与GitHub账户进行认证,并在官网上完成部署。

session_state

问题:

  • 异步函数适合非阻塞代码,但Streamlit的主循环是同步的;
  • 顶级 Streamlit 代码中不允许使用原生的 await。

快速解决方案:

  • 如果你不在异步循环中,使用Python的asyncio.run()
  • 如果在 Jupyter 中遇到循环错误,使用nest_asyncio.apply()修补循环。

进阶技巧:

  • 使用st.container()st.expander()进行视觉分组;
  • 标题和图标(如 📝 或 🔗)打破单调,引导视线;
  • Markdown支持允许引入丰富格式、链接、LaTeX方程;
  • 使用st.sidebar添加设置(比如选择结果数量,切换摘要或完整答案);
  • 通过st.markdownunsafe_allow_html=True添加自定义CSS,打造主题背景和卡片;
  • 使用st.errorst.warning优雅地显示错误信息。

控件

包括:

  • radio:单选按钮
  • checkbox:多选框
  • selectbox:下拉框
  • multiselect:下拉多选框
  • button:按钮
  • download_button:下载
  • slider:滑块
  • select_slider:选择条
  • text_input:单行文本输入
  • text_area:多行文本输入
  • number_input:数值输入
  • date_input:日期输入
  • time_input:时间输入
  • file_uploader:文件上传
  • camera_input:摄像头拍照
  • color_picker:颜色选择
  • image:展示图片
  • audio:展示音频
  • video:展示视频

Gradio

官网,开源(GitHub,40K Star,3.1K Fork)。理念:为Python函数提供最快捷的路径,使其成为一个可分享、可交互的Web演示应用,尤其是在机器学习领域。

特点:

  • 代码极简:3行代码搭出MVP界面;
  • 实时更新:改代码不用重启服务,刷新网页就能看效果;
  • 多模态交互:支持文字、图片、音频、视频输入和输出;
  • 多应用场景:快速演示AI模型效果、展示项目、收集用户反馈、教学模型可视化;
  • 支持团队协作:多人同时编辑界面,实时同步修改记录。

多模态交互

输入类型输出类型典型应用
图像/视频标签/文本/图像图像分类、目标检测、风格迁移
文本文本/代码/表格问答系统、代码生成、数据清洗
音频文本/波形图语音转写、情感分析、频谱可视化
文件/数据集可视化图表CSV分析、PDF摘要、数据探索

应用场景

  1. 学术研究:快速验证论文算法,论文复现,生成可演示Demo
  2. 企业服务:将内部模型封装为API测试工具,供非技术人员使用
  3. 教育培训:创建交互式教学模块
  4. 产品原型:用MVP界面争取投资,演示AI功能而非纯技术方案

局限与解决方案

  • 局限性:
    • 复杂布局需使用gr.Blocks(),灵活性低于Dash
    • 缺乏企业级权限管理功能
  • 解决方案:
    • 结合Flask扩展:通过gr.Interface.launch(share=False)导出API,再用Flask封装
    • 接入Okta认证:通过反向代理实现企业级权限控制

实战

安装:pip install gradio

importgradioasgrdefgreet(name,intensity):return"Hello, "+name+"!"*int(intensity)# 创建界面demo=gr.Interface(fn=greet,# 函数inputs=["text","slider"],# 对应函数的输入参数outputs=["text"],# 对应函数的返回值)demo.launch(share=True)

解读:Gradio的核心,即Interface类。提供函数、输入、输出,Gradio会自动处理剩下的所有事情:UI布局、组件渲染和数据流转。

gr.Interface更多参数:

  • live:默认False,设置为True,实时处理
  • title:标题,str格式
  • description:描述,str格式

通过share参数分享demo.launch(share=True),公网链接有效期1周。

遇到的问题,在Windows下通过Git Bash终端执行命令python gradio_demo.py,命令行没有任何输出:

换成CMD终端,输出正常:

Dash

官网,Plotly推出、基于Python的开源(GitHub,24.1K Star,2.2K Fork)框架,用于快速构建数据驱动的Web应用程序。

结合Flask的后端能力、Plotly.js(支持多种图表类型,如折线图、柱状图、散点图、热力图等)的可视化能力以及React.js的交互能力,允许用户通过简单的Python代码创建交互式的数据可视化应用,而无需掌握复杂的前端技术。特别适合数据科学家、分析师和工程师,展示数据分析结果、机器学习模型预测或其他数据驱动的功能。

原理

Dash应用由两个主要部分组成:布局(Layout)和交互性(Interactivity)。

布局

导入核心组件:from dash import Dash, html, dcc。布局定义应用程序的外观和结构,通过代码来描述的,使用dash_html_componentsdash_core_components两个库来创建HTML元素和交互式组件。Dash 2.0版本开始,这两者已被整合到dash主包中。

  • dash_html_components:提供与HTML标签对应的Python类。如,html.Div对应HTML中的<div>标签。通过这些组件,可轻松地构建页面结构/元素。
  • dash_core_components:提供更高级交互式组件,如滑块、下拉菜单、图形等。

常用交互组件

组件说明示例代码
dcc.Input创建一个文本输入框dcc.Input(id='input',type='text',placeholder='请输入内容...')
dcc.Dropdown创建一个下拉菜单dcc.Dropdown(id='dropdown',options=[{'label':'选项1','value':'1'}],value='1')
dcc.Slider创建一个滑块dcc.Slider(id='slider',min=0,max=10,step=1,value=5)
dcc.Graph创建一个交互式图表(基于Plotly.js)dcc.Graph(id='graph',figure={'data':[{'x':[1,2,3],'y':[4,1,2],'type':'bar'}]})
dcc.Textarea创建一个多行文本输入框dcc.Textarea(id='textarea',value='请输入多行文本...')
dcc.Checklist创建一个复选框列表dcc.Checklist(id='checklist',options=[{'label':'选项1','value':'1'}],value=['1'])
dcc.RadioItems创建一个单选按钮组dcc.RadioItems(id='radio',options=[{'label':'选项1','value':'1'}],value='1')
dcc.DatePickerSingle创建一个日期选择器(单选)dcc.DatePickerSingle(id='date-picker',date='2023-10-01')
dcc.DatePickerRange创建一个日期范围选择器dcc.DatePickerRange(id='date-range',start_date='2023-10-01',end_date='2023-10-07')
dcc.Markdown渲染Markdown文本dcc.Markdown('''#标题\n-列表项1''')
dcc.Store在客户端存储数据,用于跨回调共享数据dcc.Store(id='store',data={'key':'value'})
dcc.Upload创建一个文件上传组件dcc.Upload(id='upload',children=html.Div('拖放或点击上传文件'))
dcc.Tabs创建选项卡组件dcc.Tabs(id='tabs',children=[dcc.Tab(label='标签1',value='1')])
dcc.Tab创建单个选项卡(需与dcc.Tabs配合使用)dcc.Tab(label='标签1',value='1')
dcc.Interval定时触发回调的组件dcc.Interval(id='interval',interval=1000)
dcc.Location用于管理URL的组件dcc.Location(id='url',pathname='/')
dcc.Link创建一个超链接,用于页面导航(需与dcc.Location配合使用)dcc.Link('跳转到首页',href='/')
dcc.ConfirmDialog创建一个确认对话框dcc.ConfirmDialog(id='confirm',message='确定要执行此操作吗?')
dcc.ConfirmDialogProvider提供一个确认对话框(需与按钮等组件配合使用)dcc.ConfirmDialogProvider(html.Button('删除'),id='confirm-provider')
dcc.Loading创建一个加载动画组件dcc.Loading(id='loading',children=[html.Div('加载中...')])
dcc.Download用于触发文件下载的组件dcc.Download(id='download')

交互性

通过回调函数(Callback)来实现的。回调函数允许你在用户与应用程序交互时动态更新页面内容。例如,当用户选择一个下拉菜单选项时,图表可以自动更新以显示相应的数据。

回调函数通过@app.callback装饰器来定义,并指定输入和输出。输入通常是用户交互的组件(如滑块、下拉菜单等),而输出则是需要更新的组件(如图表、文本等)。

回调函数

一个典型的Dash回调函数包含以下几个部分:

  • 输入(Input):指定哪些组件的属性变化会触发回调函数
  • 输出(Output):指定回调函数执行后,哪些组件的属性会被更新
  • 状态(State):可选参数,用于传递一些不会触发回调但需要在回调中使用的数据
  • 回调函数体:包含实际的逻辑代码,用于处理输入并生成输出

工作原理

  1. 输入与输出的绑定
    输入和输出是通过Input和Output对象来指定的。Input对象指定哪些组件的哪些属性变化会触发回调函数,而Output对象指定回调函数执行后,哪些组件的哪些属性会被更新。
  2. 回调函数的触发
    当用户在界面上进行操作(输入文本、点击按钮等)时,相关的组件属性会发生变化。Dash会检测到这些变化,并自动调用与之绑定的回调函数。
  3. 回调函数的执行
    回调函数执行时,Dash会将输入属性的当前值作为参数传递给回调函数。回调函数根据这些输入值进行计算或处理,并返回输出属性的新值。Dash会自动将返回的值更新到指定的组件属性中。

高级用法

  1. 多个输入与输出:
    一个回调函数可以有多个输入和输出:
@app.callback([Output('output-div-1','children'),Output('output-div-2','children')],[Input('input-1','value'),Input('input-2','value')])defupdate_outputs(input1,input2):returnf'Input 1:{input1}',f'Input 2:{input2}'

回调函数update_outputs有两个输入和两个输出。当input-1input-2的值发生变化时,回调函数会被触发,并更新两个输出组件的children属性。

  1. 使用状态(State)
    有时候,可能需要在回调函数中使用一些不会触发回调的数据。这时可使用State对象。State对象与Input对象类似,但它不会触发回调函数。
@app.callback(Output('output-div','children'),[Input('submit-button','n_clicks')],[State('input-text','value')])defupdate_output(n_clicks,input_value):ifn_clicksisNone:return'No clicks yet'returnf'Button clicked{n_clicks}times. Input:{input_value}'

n_clicks是触发回调的输入,而input_value是回调函数中使用的状态。只有当按钮被点击时,回调函数才会被触发,但回调函数中可以使用输入框的当前值。

  1. 防止回调函数重复执行
    在某些情况下,回调函数可能会被频繁触发,导致性能问题。为避免这种情况,可使用dash.no_update来防止不必要的更新。
@app.callback(Output('output-div','children'),[Input('input-text','value')])defupdate_output(input_value):ifnotinput_value:returndash.no_updatereturnf'You have entered:{input_value}'

如果输入框的值为空,回调函数将不会更新输出组件。

如果回调函数执行缓慢,可考虑以下优化方法:

  • 减少回调函数的计算量:尽量避免在回调函数中进行复杂的计算
  • 使用缓存:对于重复的计算结果,可以使用缓存来减少计算时间
  • 异步回调:对于长时间运行的任务,可以使用异步回调来避免阻塞主线程

实战

安装:pip install dash

示例

fromdashimportDash,dcc,html,Input,Output app=Dash(__name__)app.layout=html.Div([dcc.Input(id='input',# 输入框ID,用于回调函数value='初始值',type='text'#),# 用于显示输出html.Div(id='output')])# 定义回调函数@app.callback(Output('output','children'),# 输出到id为'output'的Div的children属性Input('input','value')# 输入来自id为'input'的输入框的value属性)defupdate_output_div(input_value):returnf'你输入了:{input_value}'if__name__=='__main__':app.run_server(debug=True)

运行程序,浏览器打开http://localhost:8050

在Jupyter Notebook中使用Dash,需安装jupyter-dashpip install jupyter-dash

Dash Bootstrap Components提供Bootstrap风格的组件,用于快速构建美观的布局,安装:pip install dash-bootstrap-components,引入import dash_bootstrap_components as dbc

示例

fromdashimportDash,htmlimportdash_bootstrap_componentsasdbc app=Dash(__name__,external_stylesheets=[dbc.themes.BOOTSTRAP])app.layout=dbc.Container(children=[dbc.Row(dbc.Col(html.H1("欢迎使用Dash Bootstrap",className="text-center text-primary"))),dbc.Row(dbc.Col(dbc.Card(children=[dbc.CardHeader("卡片标题"),dbc.CardBody(children=[html.P("Bootstrap风格卡片",className="card-text")])],className="mt-4"# 设置外边距)))])if__name__=='__main__':app.run_server(debug=True)

Dash DAQ是一个用于创建数据采集和控制应用的组件库,提供丰富的样式组件,安装pip install dash-daq

示例:

fromdashimportDash,htmlimportdash_daqasdaq app=Dash(__name__)app.layout=html.Div(style={'textAlign':'center'},children=[daq.Thermometer(id='thermometer',value=25,min=0,max=100,label="温度计",style={'margin':'20px'}),daq.Gauge(id='gauge',value=50,min=0,max=100,label="压力表",style={'margin':'20px'})])if__name__=='__main__':app.run_server(debug=True)

多页面布局

在现代Web应用开发中,单页面应用(SPA)和多页面应用(MPA)是两种常见的架构模式。

单页面应用通常通过动态加载内容来提供流畅的用户体验,而多页面应用则通过多个独立的页面来组织内容。

在单页面应用中,所有内容都在一个页面中动态加载和更新,用户通过点击链接或按钮来切换不同的视图。优点是用户体验流畅,页面加载速度快;缺点是应用规模增大后,代码结构变得复杂。

多页面应用则通过多个独立的页面来组织内容,每个页面都有自己的URL和布局。优点是代码结构清晰,易于维护,缺点是页面切换时会有一定的加载延迟。

可通过dcc.Locationdcc.Link组件来实现多页面布局,前者用于跟踪当前页面的URL,后者用于在页面之间导航。结合回调函数,可根据URL动态加载不同的页面内容。

Plotly Studio

官方提供的安装程序,支持Windows、MacOS,理念:Vibe Analytics,氛围分析。

Hyperdiv

官网,开源(GitHub,934 Star,31 Fork)。用Python快速搞定浏览器端交互UI的神器。即时模式(immediate‐mode)语法,几行代码就能渲染组件。内置Shoelace组件库、Markdown渲染支持、Chart.js图表、浏览器本地存储读写,以及纯Python表单校验。

功能/环节传统前端Hyperdiv
组件库手动安装、导入内置Shoelace,一行引入
状态/渲染逻辑JS、异步/钩子Python立即模式,函数里写就行
Markdown支持单独库+配置内置Mistune,一行调用
图表展示Chart.js+对接代码内置Chart.js,API直观
本地存储localStorageAPIPythonread/write封装好
表单校验JS骚操作+验证库Python+内置校验,逻辑都在一个地方

安装:pip install hyperdiv

示例:

fromhyperdivimportapp,html,storage,form,chart# 表单classUserForm(form.Model):username=form.TextField(min_length=3)age=form.NumberField(min_value=1)@app.route("/")defindex():# 从本地存储读上一次输入data=storage.load("user_info")or{}form_ui=UserForm(data)# 表单提交回调@form_ui.on_submitdefhandle_submit(clean_data):storage.save("user_info",clean_data)chart_data={"labels":["Age"],"datasets":[{"data":[clean_data["age"]]}]}returnhtml.div([html.h3(f"你好,{clean_data['username']}!"),chart.Bar(data=chart_data)])# 页面布局returnhtml.div([html.h1("Hyperdiv 表单 + 图表 Demo"),form_ui.render()])
优点缺点
Python全栈一致,减少语言切换成本目前生态还小,组件或插件有限
即时模式写法清爽对超大规模复杂应用支持尚需验证
内置常用组件:Shoelace、Markdown、Chart浏览器兼容性待更多平台测试
阅读/写入本地存储、表单校验一站式搞定文档、教程相对少,新人上手有点陡峭
零配置启动,Demo看完就能上手高度定制化时可能需要写少量JS

对比

仅供参考

维度GradioStreamlitDash
开发效率3行代码生成完整界面需10+行基础布局代码需20+行配置式代码
交互体验支持流式传输(如视频逐帧预览)仅支持页面刷新依赖回调函数,响应较慢
组件丰富度20+专用AI组件(画布、3D模型查看器)15+通用组件(缺少AI专项优化)依赖第三方插件扩展
部署便捷性原生支持HuggingFace托管需手动配置Nginx反向代理需Docker容器化部署
学习曲线1小时可上手3小时掌握基础功能需较长时间学习

总结:

  • AI场景专精:Gradio的gr.Image(type="pil")gr.Audio(source="microphone")等组件深度适配ML需求,而Streamlit更侧重数据可视化,如数据密集型的仪表盘或数据分析
  • 性能优势:Gradio的增量更新技术(仅刷新变化区域)比Streamlit全页面刷新快3倍以上
  • 生态壁垒:Dash依赖Plotly生态,Gradio直接集成PyTorch/TensorFlow,更适合AI开发者

参考

  • 大模型导论
  • 菜鸟教程
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/25 8:07:56

MySQL行大小超限(1118错误)原理与解决方案全解析

1. 问题引入&#xff1a;当你的MySQL数据库“吃撑了”如果你正忙着把一份精心准备的数据导入MySQL&#xff0c;满心期待地敲下source your_dump.sql或者点击了Navicat的“执行SQL文件”&#xff0c;结果屏幕上突然蹦出来一行刺眼的红字&#xff1a;[ERR] 1118 - Row size too l…

作者头像 李华
网站建设 2026/8/25 8:05:55

深入解析C#字典底层原理:哈希表、冲突解决与性能优化实战

1. 项目概述&#xff1a;为什么需要深挖C#字典的底层&#xff1f;在C#开发中&#xff0c;Dictionary<TKey, TValue>几乎是每个开发者都离不开的集合类型。无论是缓存用户会话、映射配置项&#xff0c;还是处理JSON反序列化后的数据&#xff0c;字典都以其近乎O(1)的查找速…

作者头像 李华
网站建设 2026/8/25 8:04:11

SAP ABAP利用SMW0与CL_FDT_XLSP实现Excel模板化报表生成

1. 项目缘起&#xff1a;当标准ALV报表无法满足业务需求时在SAP ABAP的日常开发中&#xff0c;我们经常需要生成格式复杂、样式多变的Excel报表。标准的ALV输出到Excel功能&#xff08;REUSE_ALV_GRID_DISPLAY或CL_SALV_TABLE&#xff09;虽然方便&#xff0c;但在面对固定表头…

作者头像 李华
网站建设 2026/8/25 8:01:03

ICASSP投稿必读:如何正确使用补充材料提升论文录用率

1. 投稿前的核心认知&#xff1a;ICASSP的“附件”到底是什么&#xff1f;在信号处理、声学、通信这些硬核技术圈子里混&#xff0c;ICASSP&#xff08;IEEE International Conference on Acoustics, Speech and Signal Processing&#xff09;的地位不用我多说&#xff0c;那是…

作者头像 李华
网站建设 2026/8/25 8:00:39

《妃梦千年》第04章-御膳房的风

第4章 御膳房的风 皇帝走后&#xff0c;小翠才敢喘气&#xff1a;“娘娘&#xff0c;您怎么把安神香的事也……皇上会不会觉得是贵妃害您&#xff1f;” 林清婉坐回灯下&#xff1a;“我没说是谁。我只说香&#xff0c;没说人。要查&#xff0c;也是皇上去查。” 她心里清楚&am…

作者头像 李华