查看: 307|回复: 0

Streamlit构建交互式Web应用实战:控件缓存与销售看板

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
为什么用 Streamlit 把 Python 脚本变成 Web 应用
很多 Python 工程师用 pandas 分析、matplotlib 画图后,只能截图或放 Jupyter Notebook。要让别人打开网页使用,通常要补 HTML/CSS/JavaScript 和 Flask/Django 后端。Streamlit 的目标是让开发者只用 Python 写交互式 Web 应用,不用前端代码,保存脚本后页面自动热更新。它适合数据分析师、算法工程师、运维人员把脚本快速变成可分享原型。

环境准备与版本验证
Streamlit 是纯 Python 库,支持 Python 3.8+。建议虚拟环境隔离:
  1. python -m venv .venv
  2. source .venv/bin/activate  # Windows 使用对应 Scripts 目录下的 activate
  3. pip install streamlit
复制代码
验证安装:
  1. # check_version.py
  2. import streamlit as st
  3. # 打印当前 Streamlit 版本,确认安装成功
  4. print('Streamlit 版本:', st.__version__)
复制代码
执行 streamlit run check_version.py,会启动本地服务并自动打开浏览器,默认地址 http://localhost:8501。后续示例都使用该端口。

最小可运行示例与重跑机制
  1. # app.py
  2. import streamlit as st
  3. st.title('我的第一个 Streamlit 应用')
  4. st.write('你好,这是用纯 Python 写出来的网页!')
  5. age = st.slider('请选择你的年龄', 0, 120, 25)
  6. st.write('你选择的年龄是:', age)
复制代码
运行 streamlit run app.py。拖动滑块时数字立即变化。关键机制是:每次交互,整个脚本会从上到下重新执行,Streamlit 再把新输出映射到界面。理解这一点对后面处理状态和缓存很重要。

控件、布局、会话状态与缓存
输入控件会返回当前值:
  1. name = st.text_input('你的名字', '张三')
  2. agree = st.checkbox('我同意条款')
  3. option = st.selectbox('选择城市', ['北京', '上海', '广州'])
  4. clicked = st.button('点我提交')
复制代码
布局方面,st.sidebar 放侧边栏,st.columns 做并排:
  1. st.sidebar.title('筛选条件')
  2. threshold = st.sidebar.slider('阈值', 0, 100, 50)
  3. col1, col2 = st.columns(2)
  4. col1.metric('销量', 1280)
  5. col2.metric('增长率', '12%')
复制代码
脚本每次重跑,普通变量不会跨重跑保存。需要 st.session_state:
  1. if 'count' not in st.session_state:
  2.     st.session_state.count = 0
  3. if st.button('加一'):
  4.     st.session_state.count += 1
  5. st.write('当前计数:', st.session_state.count)
复制代码
加载大文件或训练模型很慢时,用 @st.cache_data 按入参缓存函数结果:
  1. @st.cache_data
  2. def load_data(path):
  3.     import pandas as pd
  4.     return pd.read_csv(path)
复制代码

文件上传与图表联动
Streamlit 对 pandas、matplotlib、Plotly 等生态原生友好。上传 CSV、出图、滑块过滤的组合:
  1. import pandas as pd
  2. import streamlit as st
  3. uploaded = st.file_uploader('上传一个 CSV 文件', type='csv')
  4. if uploaded is not None:
  5.     df = pd.read_csv(uploaded)
  6.     st.dataframe(df.head(20))
  7.     numeric_cols = df.select_dtypes('number').columns.tolist()
  8.     if numeric_cols:
  9.         col = st.selectbox('选择要画图的数值列', numeric_cols)
  10.         top_n = st.slider('显示前 N 行', 5, 50, 10)
  11.         st.line_chart(df[col].head(top_n))
复制代码
如果用 matplotlib:
  1. import matplotlib.pyplot as plt
  2. fig, ax = plt.subplots()
  3. ax.hist(df[col], bins=20)
  4. st.pyplot(fig)
复制代码

实战:迷你销售看板完整代码
  1. # dashboard.py
  2. import pandas as pd
  3. import streamlit as st
  4. @st.cache_data
  5. def load_data(uploaded_file):
  6.     return pd.read_csv(uploaded_file)
  7. st.set_page_config(page_title='销售看板', layout='wide')
  8. st.title('迷你销售看板')
  9. uploaded = st.file_uploader('上传销售数据 CSV(需含 city、amount、date 列)', type='csv')
  10. if uploaded is None:
  11.     st.info('请先上传一个 CSV 文件开始使用。')
  12.     st.stop()
  13. df = load_data(uploaded)
  14. df['date'] = pd.to_datetime(df['date'])
  15. cities = st.sidebar.multiselect(
  16.     '选择城市',
  17.     df['city'].unique(),
  18.     default=list(df['city'].unique())[:3]
  19. )
  20. filtered = df[df['city'].isin(cities)]
  21. col1, col2 = st.columns(2)
  22. total = filtered['amount'].sum()
  23. col1.metric('总销售额', f'{total:,.0f}')
  24. col2.metric('订单数', len(filtered))
  25. st.subheader('销售额趋势')
  26. st.line_chart(filtered.set_index('date')['amount'].resample('D').sum())
  27. st.subheader('城市汇总')
  28. st.dataframe(filtered.groupby('city')['amount'].sum().reset_index())
复制代码
运行 streamlit run dashboard.py,上传包含 city、amount、date 列的 CSV,即可得到一个可筛选、可联动的销售看板。代码里 st.stop() 用于没有上传文件时停止后续渲染,@st.cache_data 避免重复解析同一上传文件。

常见报错与排查
坑 1:ModuleNotFoundError: No module named 'streamlit'
原因:安装环境和运行环境不是同一个 Python;或者根本没安装。解决:核对 which python、pip show streamlit 的路径,虚拟环境下先 activate 再运行。
坑 2:端口 8501 被占用,自动跳到 8502/8503
启动时可能提示 Port 8501 is already in use, trying 8502。原因通常是上次服务未关闭。解决:关闭旧进程,或显式指定端口:
  1. streamlit run app.py --server.port 8503
复制代码
坑 3:点击 st.button 后状态没记住
按钮点击只在当次重跑返回 True,之后会重置,普通变量无法跨重跑保存。解决:用 st.session_state 持久化,或用 st.checkbox、st.toggle 这类天然带状态的控件替代。

下一步
需要缓存数据库连接或机器学习模型时,可以使用 @st.cache_resource;需要多页面时,把页面拆到 pages/ 目录;需要分享时,可用 Streamlit Community Cloud 免费托管。把现有 pandas 脚本外面套一层 st.,就能快速得到第一个数据应用。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-9-28 12:39 , Processed in 0.024958 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部