200字
Streamlit 入门开发手册:从零到一构建交互式数据应用(详细版)
2025-12-04
2025-12-04

Streamlit2.png

  • 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手
  • 🏳️‍🌈 个人博客主页:请点击——> 个人的博客主页 求收藏
  • 🏳️‍🌈 Github主页:请点击——> Github主页 求Star⭐
  • 🏳️‍🌈 知乎主页:请点击——> 知乎主页 求关注
  • 🏳️‍🌈 CSDN博客主页:请点击——> CSDN的博客主页 求关注
  • 👍 该系列文章专栏:请点击——>Python办公自动化专栏 求订阅
  • 🕷 此外还有爬虫专栏:请点击——>Python爬虫基础专栏 求订阅
  • 📕 此外还有python基础专栏:请点击——>Python基础学习专栏 求订阅
  • 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
  • ❤️ 欢迎各位佬关注! ❤️

Streamlit 入门开发手册:从零到一构建交互式数据应用(详细版)

引言

在数据科学和机器学习领域,我们经常需要将复杂的模型和分析结果以直观、交互式的方式呈现给非技术用户或团队成员。传统上,这可能涉及到前端开发、后端API构建以及数据库交互,过程复杂且耗时。然而,随着 Streamlit 的出现,这一切都变得前所未有地简单。

Streamlit 是什么?

Streamlit 是一个开源的 Python 库,它允许数据科学家和机器学习工程师仅使用纯 Python 代码,就能快速创建美观、高性能且高度交互式的数据应用和 Web 界面。它将数据脚本转化为可分享的 Web 应用,无需任何前端(HTML/CSS/JavaScript)知识。

为什么选择 Streamlit?

  • 纯 Python 开发: 无需学习新的语言或框架,用你熟悉的 Python 即可构建应用。
  • 开发效率高: 几行代码就能实现复杂的功能,大大缩短开发周期。
  • 交互性强: 内置丰富的 UI 组件,轻松实现用户输入、数据展示和图表交互。
  • 实时更新: 代码更改后,应用会自动更新,即时反馈开发效果。
  • 社区活跃: 拥有庞大的用户社区和详尽的官方文档,遇到问题容易找到解决方案。

本手册旨在为完全的 Streamlit 初学者提供一份详尽的入门指南。我们将从环境搭建开始,逐步深入到核心组件、布局、状态管理和部署,助你从零开始,快速掌握 Streamlit 的开发精髓。

前置条件

在开始 Streamlit 开发之前,你需要准备好以下环境和基础知识:

1. Python 基础

  • Python 语言基础: 了解 Python 的基本语法、数据结构(列表、字典)、函数定义和模块导入等。
  • 版本要求: Streamlit 通常支持 Python 3.7 及以上版本。建议使用较新的 Python 3.9 或 3.10 版本以获得最佳兼容性。

2. 环境准备

强烈建议使用虚拟环境(Virtual Environment)来管理项目依赖,避免不同项目间的库版本冲突。

  • 安装 Python: 如果你的系统尚未安装 Python,请访问 Python 官方网站 下载并安装。

  • 创建并激活虚拟环境(推荐):

    # 创建一个名为 'streamlit_env' 的虚拟环境
    python -m venv streamlit_env
    
    # 激活虚拟环境
    # macOS/Linux:
    source streamlit_env/bin/activate
    # Windows:
    streamlit_env\Scripts\activate
    

    当你看到命令行前缀变为 (streamlit_env) 时,表示虚拟环境已成功激活。

详细开发指南

1. 安装 Streamlit

在激活的虚拟环境中,使用 pip 安装 Streamlit:

pip install streamlit

安装完成后,你可以通过运行一个 Streamlit 示例应用来验证安装是否成功:

streamlit hello

这会打开一个浏览器窗口,显示 Streamlit 的官方示例应用。

2. 你的第一个 Streamlit 应用

让我们从一个最简单的 Streamlit 应用开始。

  1. 创建一个名为 my_app.py 的 Python 文件。

  2. 在文件中输入以下代码:

    # my_app.py
    import streamlit as st
    
    st.title("我的第一个 Streamlit 应用")
    st.write("欢迎来到 Streamlit 的世界!")
    st.write("这是一个简单的文本展示。")
    
    # 你也可以使用 Markdown 语法
    st.markdown("---")
    st.markdown("### 这是一个三级标题")
    st.markdown("**加粗文本** 和 *斜体文本*。")
    
  3. 保存文件。

  4. 在命令行中(确保虚拟环境已激活,并且你在 my_app.py 所在的目录下),运行你的应用:

    streamlit run my_app.py
    

    运行后,Streamlit 会自动在你的默认浏览器中打开一个新标签页,显示你的应用(通常地址是 http://localhost:8501)。

    注意: Streamlit 应用在运行时会从上到下执行整个脚本。每次用户与应用交互(例如点击按钮、改变滑块),整个脚本都会重新运行。这是 Streamlit 工作方式的核心。

3. 基础 UI 组件

Streamlit 提供了丰富的 UI 组件,用于显示信息、接收用户输入和展示数据。

3.1 文本与数据展示

  • 标题: st.title(), st.header(), st.subheader()
    st.title("应用主标题")
    st.header("一级章节标题")
    st.subheader("二级小节标题")
    
  • 普通文本: st.text()
    st.text("这是一段普通文本。")
    
  • Markdown 文本: st.markdown() - 支持所有标准 Markdown 语法。
    st.markdown("""
    ### Markdown 示例
    - 列表项 1
    - 列表项 2
    
    `st.markdown()` 支持 **加粗**、*斜体* 和 `代码块`。
    """)
    
  • LaTeX 公式: st.latex()
    st.latex(r'''
        a + ar + ar^2 + \dots + ar^{n-1} = \sum_{k=0}^{n-1} ar^k
    ''')
    
  • 代码块: st.code()
    code = '''def hello():
        print("Hello, Streamlit!")'''
    st.code(code, language='python')
    
  • 数据框: st.dataframe() - 展示 Pandas DataFrame。
    import pandas as pd
    df = pd.DataFrame({
        'col1': [1, 2, 3, 4],
        'col2': ['A', 'B', 'C', 'D']
    })
    st.dataframe(df)
    
  • 静态表格: st.table() - 展示静态表格。
    st.table(df) # 也可以是列表的列表或字典
    
  • JSON 数据: st.json()
    st.json({'foo': 'bar', 'baz': 'qux'})
    
  • 进度条与状态: st.progress(), st.spinner()
    import time
    st.write("开始加载数据...")
    latest_iteration = st.empty()
    bar = st.progress(0)
    
    for i in range(100):
        # Update the progress bar with each iteration.
        latest_iteration.text(f'Iteration {i+1}')
        bar.progress(i + 1)
        time.sleep(0.05)
    
    st.success("数据加载完成!")
    
    with st.spinner('正在执行复杂计算...'):
        time.sleep(3)
    st.success('计算完毕!')
    

3.2 媒体展示

  • 图片: st.image()
    # st.image("path/to/your/image.jpg", caption="图片标题", use_column_width=True)
    # 示例使用网络图片
    st.image("https://www.streamlit.io/images/brand/streamlit-logo-primary-full-color.svg",
             caption="Streamlit Logo",
             width=200)
    
  • 音频: st.audio()
    # st.audio("path/to/your/audio.mp3")
    
  • 视频: st.video()
    # st.video("path/to/your/video.mp4")
    # 示例使用 YouTube 视频
    # st.video("https://www.youtube.com/watch?v=YOUR_VIDEO_ID")
    

3.3 交互式组件(Widgets)

这些组件允许用户与应用进行交互,并返回用户输入的值。

  • 按钮: st.button()
    if st.button('点击我!'):
        st.write('你点击了按钮。')
    
  • 复选框: st.checkbox()
    agree = st.checkbox('我同意条款和条件')
    if agree:
        st.write('感谢您的同意!')
    
  • 单选按钮: st.radio()
    genre = st.radio(
        "你最喜欢的电影类型是什么?",
        ('喜剧', '剧情', '科幻', '动作'))
    if genre == '喜剧':
        st.write('哈哈哈!')
    else:
        st.write(f'你选择了 {genre}。')
    
  • 选择框(下拉列表): st.selectbox()
    option = st.selectbox(
        '请选择你最喜欢的水果:',
        ('苹果', '香蕉', '橘子', '草莓'))
    st.write('你选择的水果是:', option)
    
  • 多选框: st.multiselect()
    options = st.multiselect(
        '你最喜欢哪些颜色?',
        ['绿色', '黄色', '红色', '蓝色', '黑色'],
        ['黄色', '红色']) # 默认选中项
    st.write('你选择了:', options)
    
  • 滑块: st.slider()
    age = st.slider('你的年龄是多少?', 0, 100, 25) # min, max, default
    st.write("我", age, "岁。")
    
    values = st.slider(
        '选择一个范围',
        0.0, 100.0, (25.0, 75.0)) # 范围滑块
    st.write('选择的范围是:', values)
    
  • 文本输入框: st.text_input(), st.text_area()
    title = st.text_input('电影名称', '肖申克的救赎')
    st.write('你输入的电影名称是:', title)
    
    comment = st.text_area('评论', '在这里输入你的评论...')
    st.write('你的评论是:', comment)
    
  • 数字输入框: st.number_input()
    number = st.number_input('输入一个数字', min_value=0, max_value=100, value=50, step=1)
    st.write('你输入的数字是:', number)
    
  • 日期输入: st.date_input()
    import datetime
    d = st.date_input(
        "你的生日是哪天?",
        datetime.date(2000, 1, 1))
    st.write('你的生日是:', d)
    
  • 文件上传: st.file_uploader()
    uploaded_file = st.file_uploader("选择一个 CSV 文件", type=['csv', 'txt'])
    if uploaded_file is not None:
        # 读取文件内容
        df_uploaded = pd.read_csv(uploaded_file)
        st.write("上传的文件内容:")
        st.dataframe(df_uploaded)
    
  • 颜色选择器: st.color_picker()
    color = st.color_picker('选择一个颜色', '#00f900')
    st.write('你选择的颜色是:', color)
    

4. 布局与组织

为了更好地组织应用内容,Streamlit 提供了多种布局选项。

4.1 侧边栏 st.sidebar

侧边栏通常用于放置配置选项或导航菜单。

# my_app_with_sidebar.py
import streamlit as st

st.title("带侧边栏的应用")

st.sidebar.header("侧边栏配置")
name = st.sidebar.text_input("请输入你的名字", "游客")
age = st.sidebar.slider("你的年龄", 0, 100, 25)

st.write(f"你好, **{name}**! 你今年 {age} 岁。")

st.markdown("---")
st.write("这是主内容区域。")

运行 streamlit run my_app_with_sidebar.py 查看效果。

4.2 列 st.columns()

将页面内容分成多列,实现横向布局。

import streamlit as st

st.header("多列布局示例")

col1, col2, col3 = st.columns(3) # 分成三列,等宽

with col1:
    st.subheader("第一列")
    st.write("这是第一列的内容。")
    st.button("按钮 A")

with col2:
    st.subheader("第二列")
    st.write("这是第二列的内容。")
    st.button("按钮 B")

with col3:
    st.subheader("第三列")
    st.write("这是第三列的内容。")
    st.button("按钮 C")

st.markdown("---")

# 也可以指定列的宽度比例
col_a, col_b = st.columns([1, 3]) # 第一列宽度是第二列的三分之一

with col_a:
    st.subheader("窄列")
    st.write("这列比较窄。")

with col_b:
    st.subheader("宽列")
    st.write("这列比较宽,可以放更多内容,比如一个图表。")
    st.line_chart([1, 5, 2, 6, 3, 7])

4.3 展开器 st.expander()

用于折叠和展开内容,节省页面空间。

import streamlit as st

st.header("展开器示例")

with st.expander("点击查看更多信息"):
    st.write("这些是你可以折叠起来的详细信息。")
    st.image("https://static.streamlit.io/examples/cat.jpg", width=100)

st.write("这是展开器下面的内容。")

4.4 选项卡 st.tabs()

将内容组织在不同的选项卡中,方便用户切换查看。

import streamlit as st

st.header("选项卡示例")

tab1, tab2, tab3 = st.tabs(["数据分析", "模型预测", "设置"])

with tab1:
    st.subheader("数据分析")
    st.write("在这里展示你的数据洞察和图表。")
    st.line_chart({"data": [10, 20, 15, 25, 30]})

with tab2:
    st.subheader("模型预测")
    st.write("输入参数进行模型预测。")
    input_value = st.number_input("输入一个值", 0, 100, 50)
    st.write(f"模型预测结果:{input_value * 2}")

with tab3:
    st.subheader("应用设置")
    st.checkbox("启用高级功能")
    st.text_input("API Key", type="password")

5. 显示数据与图表

Streamlit 与流行的 Python 数据科学库(如 Pandas, Matplotlib, Plotly, Altair, Bokeh 等)无缝集成。

  • Pandas DataFrame: 已在 st.dataframe() 中展示。

  • Matplotlib 图表: st.pyplot()

    import matplotlib.pyplot as plt
    import numpy as np
    
    st.subheader("Matplotlib 图表示例")
    arr = np.random.normal(1, 1, size=100)
    fig, ax = plt.subplots()
    ax.hist(arr, bins=20)
    st.pyplot(fig)
    
  • Plotly 图表: st.plotly_chart()

    import plotly.express as px
    
    st.subheader("Plotly 图表示例")
    df_plotly = px.data.iris()
    fig_plotly = px.scatter(df_plotly, x="sepal_width", y="sepal_length", color="species")
    st.plotly_chart(fig_plotly)
    
  • Altair 图表: st.altair_chart()

  • 内置简单图表: Streamlit 也提供了一些快速生成简单图表的函数。

    • st.line_chart()
    • st.area_chart()
    • st.bar_chart()
    st.subheader("Streamlit 内置图表")
    chart_data = pd.DataFrame(
        np.random.randn(20, 3),
        columns=['a', 'b', 'c']
    )
    st.line_chart(chart_data)
    

6. 状态管理 st.session_state

由于 Streamlit 的每次交互都会重新运行整个脚本,因此需要在多次运行之间“记住”某些变量的值。st.session_state 是一个字典,用于在会话期间存储和访问变量。

import streamlit as st

st.title("状态管理示例:计数器")

# 初始化 session_state 中的计数器,如果它不存在
if 'count' not in st.session_state:
    st.session_state.count = 0

st.write(f"当前计数: {st.session_state.count}")

col_inc, col_dec = st.columns(2)

with col_inc:
    if st.button('增加计数'):
        st.session_state.count += 1
        # Streamlit 会自动重新运行脚本,更新显示

with col_dec:
    if st.button('减少计数'):
        st.session_state.count -= 1
        # Streamlit 会自动重新运行脚本,更新显示

st.markdown("---")
# 另一个例子:记住文本输入框的值
if 'my_text' not in st.session_state:
    st.session_state.my_text = "默认文本"

# 当用户输入时,将值存入 session_state
st.session_state.my_text = st.text_input("请输入一些文本", st.session_state.my_text, key="text_input_widget")
st.write(f"你输入的文本是: {st.session_state.my_text}")

# 按钮点击后,文本输入框的值不会丢失
if st.button("打印文本"):
    st.write(f"再次打印: {st.session_state.my_text}")

key 参数的重要性: 对于需要保持独立状态的 widgets (如 st.text_input, st.slider 等),特别是当它们可能在条件语句中出现时,为它们设置唯一的 key 参数非常重要。key 帮助 Streamlit 识别和管理 widgets 的状态。如果一个 widget 的 key 未改变,Streamlit 会尝试保持其值。

7. 缓存 st.cache_datast.cache_resource

对于计算量大或数据加载耗时的函数,每次脚本重新运行时都会导致性能下降。Streamlit 的缓存机制可以显著提升应用性能。

  • @st.cache_data 用于缓存函数返回的数据。当函数参数不变时,它会直接返回之前缓存的结果,而不会重新执行函数。适用于加载数据、数据预处理等。
  • @st.cache_resource 用于缓存资源对象,例如机器学习模型、数据库连接等,这些资源在应用生命周期内通常只需要加载一次。
import streamlit as st
import time
import pandas as pd
from sklearn.linear_model import LinearRegression

st.title("缓存机制示例")

# 使用 st.cache_data 缓存数据加载函数
@st.cache_data
def load_data():
    time.sleep(2) # 模拟耗时的数据加载
    data = pd.DataFrame({
        'x': range(100),
        'y': [i * 2 + np.random.randint(-5, 5) for i in range(100)]
    })
    return data

# 使用 st.cache_resource 缓存模型加载函数
@st.cache_resource
def load_model():
    time.sleep(3) # 模拟耗时的模型加载
    model = LinearRegression()
    # 假设我们在这里训练了一个简单的模型
    data = load_data() # 注意这里会调用缓存的数据
    model.fit(data[['x']], data['y'])
    return model

st.write("---")
st.subheader("数据加载")
with st.spinner("正在加载数据 (首次运行会慢)..."):
    my_data = load_data()
st.write("数据加载完毕!")
st.dataframe(my_data.head())

st.write("---")
st.subheader("模型加载与预测")
with st.spinner("正在加载模型 (首次运行会慢)..."):
    my_model = load_model()
st.write("模型加载完毕!")

# 进行预测
input_x = st.slider("选择 X 值进行预测", 0, 99, 50)
prediction = my_model.predict([[input_x]])
st.write(f"当 X = {input_x} 时,预测 Y = {prediction[0]:.2f}")

st.write("尝试多次调整滑块,你会发现数据和模型加载只会在第一次执行时耗时。")

8. 表单 st.form()

当你的应用有多个输入组件,并且你希望它们只有在用户点击提交按钮后才触发脚本重新运行时,st.form() 就非常有用。这可以避免每次输入变化都导致整个页面刷新,提升用户体验。

import streamlit as st

st.title("表单示例")

with st.form("my_form"):
    st.write("在表单中输入信息")
    name = st.text_input("姓名")
    age = st.number_input("年龄", min_value=0, max_value=120, value=30)
    occupation = st.selectbox("职业", ["工程师", "设计师", "学生", "其他"])

    # 表单中的所有元素必须在 form 块内
    submitted = st.form_submit_button("提交")

if submitted:
    st.write(f"提交成功!")
    st.write(f"姓名: {name}")
    st.write(f"年龄: {age}")
    st.write(f"职业: {occupation}")
else:
    st.write("请填写表单并提交。")

常见陷阱与最佳实践

1. 理解 Streamlit 的脚本重跑机制

  • 核心原理: Streamlit 应用的每次交互(如按钮点击、滑块拖动、文本输入)都会导致整个 Python 脚本从头到尾重新运行。
  • 影响: 如果你的脚本中有耗时的操作(如数据加载、模型训练),每次交互都会重复执行,导致应用变慢。
  • 解决方案:
    • 使用 st.cache_datast.cache_resource 缓存耗时的数据加载和模型初始化。
    • 使用 st.session_state 存储需要在多次运行之间保持的变量。
    • 使用 st.form 批量处理用户输入,减少不必要的重跑。

2. Widget 的 key 参数

  • 何时需要: 当在条件语句(if/else)中创建同一个 widget,或者在同一页面上有多个相同类型的 widget 且它们需要独立的状态时,必须使用唯一的 key

  • 作用: key 帮助 Streamlit 唯一标识一个 widget,从而正确地管理其状态。

  • 示例:

    if st.checkbox("显示高级选项"):
        st.text_input("高级设置 1", key="advanced_setting_1")
    else:
        st.text_input("普通设置 1", key="normal_setting_1") # 即使名称不同,如果Streamlit内部哈希值相同,也可能冲突
    

    这里 key 是必不可少的,因为 st.text_input 可能在不同的分支中创建。

3. 正确使用 st.session_state

  • 初始化: 始终在使用 st.session_state 变量之前进行初始化,通常放在脚本顶部,使用 if 'var_name' not in st.session_state: 进行检查。
  • 更新: 可以直接通过 st.session_state.var_name = valuest.session_state['var_name'] = value 来更新。
  • 与 Widget 绑定: 许多 widgets 允许你通过 valueon_change 参数直接与 st.session_state 绑定,或者通过 key 参数将 widget 的当前值自动存储到 st.session_state[key] 中。

4. 优化性能

  • 缓存: 如前所述,充分利用 @st.cache_data@st.cache_resource
  • 数据量: 避免在 Streamlit 应用中直接处理超大规模数据集。考虑在后端进行预处理,或者只加载需要展示的子集。
  • 异步操作: Streamlit 本身是同步的,但你可以结合 threadingasyncio 来处理一些非阻塞的后台任务(但需要谨慎处理 UI 更新)。
  • 资源释放: 如果使用了外部资源(如数据库连接),确保在不再需要时关闭它们。

5. 错误处理与用户反馈

  • st.error() / st.warning() / st.info() / st.success() 提供清晰的用户反馈。
  • st.exception() 在捕获到异常时显示详细的错误信息。
  • 日志: 使用 Python 的 logging 模块记录应用运行时的信息和错误,方便调试。

资源与总结

恭喜你!你已经完成了 Streamlit 入门开发手册的详细学习。现在,你已经掌握了构建交互式数据应用所需的核心知识和技能。

进一步学习资源

总结

Streamlit 极大地降低了数据科学家和开发者构建 Web 应用的门槛。通过本手册的学习,你应该能够:

  • 搭建 Streamlit 开发环境。
  • 创建并运行你的第一个 Streamlit 应用。
  • 熟练运用各种 UI 组件展示数据和接收用户输入。
  • 使用布局组件优化应用界面。
  • 集成数据科学库进行数据可视化。
  • 理解并运用状态管理和缓存机制提升应用性能。
  • 了解常见陷阱并掌握最佳实践。

现在,是时候将你的数据洞察和模型转化为功能强大的交互式应用了!祝你在 Streamlit 的世界中探索愉快,创作出令人惊艳的作品!

  • 希望对初学者有帮助;致力于办公自动化的小小程序员一枚
  • 希望能得到大家的【❤️一个免费关注❤️】感谢!
  • 求个 🤞 关注 🤞 +❤️ 喜欢 ❤️ +👍 收藏 👍
  • 此外还有办公自动化专栏,欢迎大家订阅:Python办公自动化专栏
  • 此外还有爬虫专栏,欢迎大家订阅:Python爬虫基础专栏
  • 此外还有Python基础专栏,欢迎大家订阅:Python基础学习专栏
Streamlit 入门开发手册:从零到一构建交互式数据应用(详细版)
作者
一晌小贪欢
发表于
2025-12-04
License
CC BY-NC-SA 4.0

评论