社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

一个神奇的 Python 库:Streamlit,把脚本秒变 Web 应用

程序员老朱 • 4 月前 • 249 次点击  

下面是一个简单数据分析:

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应用了。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/198096