一个神奇的 Python 库:Streamlit,把脚本秒变 Web 应用
一个神奇的 Python 库:Streamlit,把脚本秒变 Web 应用
原创 老朱 程序员老朱 2026年6月24日 18:17 湖南 听全文
下面是一个简单数据分析:
df = pd.read_csv("销售数据.csv")
result = df.groupby("地区").agg({"销售额": "sum", "利润": "mean"})
print(result)
输出:

但这个输出内容你怎么给你的老板看呢?截图通过微信发给你老板?
实际上他想要一个能打开的链接、能筛选的日期、能下载的表格,一个可视化界面。
这不是你一个人的困境。每一个做数据分析的 Python 开发者都卡在「分析能力满分,交付能力零分」的断层上——你能写出复杂的数据管道,但没法让业务方自己探索数据。
「Streamlit 就是为填这个断层而生的。」 它的设计哲学非常简单:你只需要写 Python,它帮你生成 Web 界面。
上面代码仅需简单改造就能变成一个漂亮的 Web 应用:
import streamlit as st
import pandas as pd
st.title("销售数据看板")
df = pd.read_csv("销售数据.csv")
st.dataframe(df) # 可排序、可筛选的交互式表格
st.bar_chart(df.groupby("地区")["销售额"].sum())
通过下面shell安装、运行
pip install streamlit # 安装
streamlit run app.py # 运行
浏览器自动打开 http://localhost:8501。 你看到的不是一个终端输出,而是一个「完整的 Web 应用」——有标题、有表格(可以点击列头排序)、有柱状图。你没写一行 HTML。

一、Streamlit 是什么?
Streamlit 是一个开源的 Python 库,能够让你「纯用 Python 代码」快速构建和分享数据 Web 应用。不需要 HTML、CSS 或 JavaScript,几分钟就能把一个 Python 脚本变成可交互的网页应用。
它尤其适合数据科学家、机器学习工程师和需要快速做原型演示的开发者。 你写的是线性 Python 脚本,但它呈现的是一个有状态的交互式 Web 应用。
二、安装
环境要求:Python 3.8 ~ 3.13。
pip install streamlit
安装完成后,验证是否成功:
streamlit hello
这会启动一个本地服务,并在浏览器中打开 Streamlit 的官方演示页面。

三、第一个应用
创建一个 app.py 文件:
import streamlit as st
import pandas as pd
import numpy as np
st.title("我的第一个 Streamlit 应用")
st.write("Hello, Streamlit!")
# 生成一些随机数据并绘制折线图
chart_data = pd.DataFrame(
np.random.randn(20, 3),
columns=["A", "B", "C"]
)
st.line_chart(chart_data)
在终端中运行:
streamlit run app.py

四、常用组件详解
4.1 文本组件
文本组件负责将信息直观地呈现给用户。不同于普通的 print(),Streamlit 的文本组件会渲染在浏览器中,并支持丰富的格式和层级结构。
st.title("这是一级标题") # 最大号标题
st.header("这是二级标题") # 中号标题
st.subheader("这是三级标题") # 小号标题
st.markdown("支持 **Markdown** 语法")
st.text("纯文本内容")
st.code("print('Hello')", language="python") # 代码块,带语法高亮
st.caption("这是一段说明性小字")
st.latex(r"e^{i\pi} + 1 = 0") # LaTeX 公式
输出:

4.2 数据展示
数据展示组件是 Streamlit 作为数据分析工具的核心优势。它们不仅展示数据,还提供了交互能力,帮助用户快速洞察规律。
data = {
"姓名": ["张三", "李四", "王五"],
"年龄": [25, 30, 28],
"城市": ["北京", "上海", "广州"]
}
df = pd.DataFrame(data)
st.dataframe(df) # 可交互的表格(支持排序、缩放)
st.table(df) # 静态表格
st.json(data) # JSON 格式化展示
st.metric("温度", "24°C", delta="1.5°C") # 指标卡片,delta 表示变化量
输出:

4.3 图表组件
Streamlit 内置了几种常用图表,也支持 Matplotlib、Plotly、Altair 等第三方图表库。
import pandas as pd
import numpy as np
import streamlit as st
data = {
"姓名": ["张三", "李四", "王五"],
"年龄": [25, 30, 28],
"城市": ["北京", "上海", "广州"],
"薪资": [15000, 18000, 16000]
}
df = pd.DataFrame(data)
# st.map 需要 latitude / longitude 列(或 lat / lon)
location_data = pd.DataFrame({
"latitude": [39.9042, 31.2304, 23.1291, 22.5431, 30.5728],
"longitude": [116.4074, 121.4737, 113.2644, 114.0579, 104.0668],
"city": ["北京", "上海", "广州", "深圳", "成都"]
})
import matplotlib.pyplot as plt
# 内置图表(基于 Altair)
# 只选数值列做图表,避免字符串列报错
df_chart = df.set_index("姓名")[["年龄", "薪资"]]
st.line_chart(df_chart) # 折线图
st.area_chart(df_chart) # 面积图
st.bar_chart(df_chart) # 柱状图
st.scatter_chart(df, x="年龄", y="薪资") # 散点图
st.map(location_data) # 地图(需 latitude/longitude 列)
# Matplotlib
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [1, 4, 2])
st.pyplot(fig)
# Plotly(交互式图表)
import plotly.express as px
fig = px.scatter(df, x="年龄", y="薪资")
st.plotly_chart(fig, use_container_width=True)
产生多种图表, 输出:

4.4 输入组件
输入组件是 Streamlit 的灵魂。用户每次操作控件(如滑动、点击、输入),整个 Python 脚本都会从上到下重新执行,变量值自动更新为控件当前状态。这种 “数据流驱动” 的模式极大地简化了后端逻辑。
# 文本输入
name = st.text_input("请输入你的名字", value="")
password = st.text_input("请输入密码", type="password")
comment = st.text_area("请输入评论", height=150)
# 数字输入
age = st.number_input("请输入年龄", min_value=0, max_value=150, value=25, step=1)
score = st.slider("评分", min_value=0.0, max_value=10.0, value=5.0, step=0.5)
# 选择类
option = st.selectbox("选择城市", ["北京", "上海", "广州", "深圳"])
options = st.multiselect("选择爱好", ["阅读", "运动", "音乐", "旅游"], default=["阅读"])
checked = st.checkbox("我同意条款")
color = st.color_picker("选择颜色", "#00FFAA")
# 日期与时间
date = st.date_input("选择日期")
time = st.time_input("选择时间")
# 文件上传
uploaded_file = st.file_uploader("上传文件", type=["csv", "txt", "png", "jpg"])
# 按钮
if st.button("点击我"):
st.success(f"你好,{name}!")
# 下载按钮
st.download_button(
label="下载 CSV",
data=df.to_csv(index=False).encode("utf-8"),
file_name="data.csv",
mime="text/csv"
)
输出:

4.5 状态与反馈
优秀的应用不仅功能完备,还应该给用户清晰的操作反馈。Streamlit 提供了一套完整的反馈机制,涵盖成功、提示、警告、错误和进度追踪。
st.success("操作成功!") # 绿色提示条
st.info("这是一条信息提示") # 蓝色提示条
st.warning("请注意!") # 黄色警告条
st.error("出错了!") # 红色错误条
# 进度条与等待
with st.spinner("处理中,请稍候..."):
time.sleep(2)
st.success("完成!")
progress_bar = st.progress(0)
for i in range(100):
time.sleep(0.01)
progress_bar.progress(i + 1)
# 吐司通知
st.toast("任务已完成!", icon="🎉")
# 全局异常捕获
try:
1 / 0
except Exception as e:
st.exception(e) # 展开显示完整的 traceback
输出:

4.6 布局组件
默认情况下,Streamlit 组件按顺序垂直排列。布局组件让你能够像画板一样自由组织页面结构,将应用从“长文档”升级为“仪表盘”。
# 侧边栏
with st.sidebar:
st.header("侧边栏")
option = st.radio("导航", ["首页", "数据", "关于"])
# 列布局
col1, col2, col3 = st.columns(3)
with col1:
st.metric("收入", "¥12,000", "8%")
with col2:
st.metric("支出", "¥5,800", "-12%")
with col3:
st.metric("净利润", "¥6,200", "21%")
# 容器
container = st.container(border=True)
container.write("这是带边框的容器")
# 可展开区域
with st.expander("点击查看详情"):
st.write("这里是详细内容")
# 多标签页
tab1, tab2, tab3 = st.tabs(["概况", "图表", "数据"])
with tab1:
st.write("概况页面内容")
with tab2:
st.line_chart(np.random.randn(30, 3))
with tab3:
st.dataframe(df)
输出:

4.7 缓存与性能
理解 Streamlit 的执行模型(每次交互全量重跑)是性能优化的前提。如果没有缓存,每次滑块拖动或按钮点击都会重新加载几十 MB 的 CSV 或重新训练模型,应用会变得极其卡顿。
@st.cache_data 会缓存函数返回值,脚本重新运行时如果参数未变则直接返回缓存结果,避免重复加载数据或重复计算。
# 告诉 Streamlit:如果 URL 没变,就不重新读取
@st.cache_data
def load_data(url):
# 模拟耗时加载,实际项目中为 pd.read_csv(url)
return pd.read_csv(url)
# 第一次运行会下载并缓存,后续滑块变动时直接返回缓存
df = load_data("https://example.com/large-dataset.csv")
# 带 TTL 的缓存(适用于动态数据)
@st.cache_data(ttl=600) # 10 分钟后自动刷新
def fetch_live_data():
return requests.get("https://api.example.com/live").json()
五、会话状态(Session State)
为什么需要会话状态?
Streamlit 的“重跑”机制虽然简化了逻辑,但也带来了一个棘手问题:本地变量会在每次交互后重置。比如你写了一个 count = 0,点击按钮 count += 1,页面刷新后 count 又被设回 0。这就无法实现“计数器”、“购物车”、“多步骤表单向导”等需要跨交互记忆的场景。
典型应用场景
-
页面导航:用 st.session_state.page 记录当前所在页面,点击侧边栏菜单时切换。
-
表单向导:分步收集用户信息,每一步将输入保存到 session_state,最后统一提交。
-
防重复提交:通过 st.session_state.submitted 布尔值控制按钮的可用状态。
Streamlit 默认在每次交互时从头执行脚本。当你需要跨交互保存变量时(比如计数器),就需要 st.session_state:
# 初始化计数器(确保首次访问时存在)
if"count"notin st.session_state:
st.session_state.count = 0
# 计数按钮 - 每次点击触发 +1
if st.button("➕ 点击 +1"):
st.session_state.count += 1
st.metric("点击次数", st.session_state.count)
# 重置按钮 - 将计数归零
if st.button("🔄 重置"):
st.session_state.count = 0
# 小技巧:利用 session_state 实现“首次运行”标记
if"first_run"notin st.session_state:
st.session_state.first_run = True
st.info("👋 欢迎首次访问!")
else:
st.write(f"你已经访问了 {st.session_state.count} 次")
# 清除特定状态(用于退出登录或清空表单)
# del st.session_state["user_info"]
st.session_state 本质上是一个字典,但支持属性访问(st.session_state.count 等价于 st.session_state["count"])。
结语
本文主要讲解streamlit的基本安装及简单示例,着重介绍了该项目能够使用的各种组件,现在 你可以通过各组件构建简单的web应用了。
更多推荐



所有评论(0)