Session State

会话状态是一种在每次用户会话的重新运行之间共享变量的方式。除了能够存储和保持状态外,Streamlit 还提供了使用回调函数操作状态的能力。会话状态在多页面应用中的应用之间也保持持久性。

查看这个由Streamlit开发者倡导者Marisa Smith博士制作的Session State基础教程视频,开始学习:

会话状态API遵循基于字段的API,这与Python字典非常相似:

# Initialization if 'key' not in st.session_state: st.session_state['key'] = 'value' # Session State also supports attribute based syntax if 'key' not in st.session_state: st.session_state.key = 'value'

读取Session State中某个项目的值并通过传递给st.write来显示它:

# Read st.write(st.session_state.key) # Outputs: value

通过为会话状态中的项目赋值来更新它:

st.session_state.key = 'value2' # Attribute API st.session_state['key'] = 'value2' # Dictionary like API

好奇会话状态中有什么?使用 st.write 或魔法:

st.write(st.session_state) # With magic: st.session_state

如果访问了未初始化的变量,Streamlit 会抛出一个方便的异常:

st.write(st.session_state['value']) # Throws an exception!
state-uninitialized-exception

使用语法删除会话状态中的项目,就像删除任何Python字典中的项目一样:

# Delete a single key-value pair del st.session_state[key] # Delete all the items in Session state for key in st.session_state.keys(): del st.session_state[key]

会话状态也可以通过进入设置 → 清除缓存,然后重新运行应用程序来清除。

state-clear-cache

每个带有键的小部件都会自动添加到会话状态中:

st.text_input("Your name", key="name") # This exists now: st.session_state.name

回调是一个python函数,当输入小部件发生变化时会被调用。

执行顺序:在响应事件更新会话状态时,首先执行回调函数,然后应用程序从上到下执行。

回调函数可以通过参数 on_change(或 on_click)、argskwargs 与小部件一起使用:

参数

  • on_changeon_click - 用作回调的函数名称
  • args (tuple) - 传递给回调函数的参数列表
  • kwargs (dict) - 传递给回调函数的命名参数

支持on_change事件的小部件:

  • st.checkbox
  • st.color_picker
  • st.date_input
  • st.data_editor
  • st.file_uploader
  • st.multiselect
  • st.number_input
  • st.radio
  • st.select_slider
  • st.selectbox
  • st.slider
  • st.text_area
  • st.text_input
  • st.time_input
  • st.toggle

支持on_click事件的小部件:

  • st.button
  • st.download_button
  • st.form_submit_button

要添加回调,请在部件声明上方定义一个回调函数,并通过on_change(或on_click)参数将其传递给部件。

表单中的小部件可以通过会话状态API访问和设置它们的值。st.form_submit_button可以关联一个回调函数。点击提交按钮时,回调函数会被执行。例如:

def form_callback(): st.write(st.session_state.my_slider) st.write(st.session_state.my_checkbox) with st.form(key='my_form'): slider_input = st.slider('My slider', 0, 10, 5, key='my_slider') checkbox_input = st.checkbox('Yes or No', key='my_checkbox') submit_button = st.form_submit_button(label='Submit', on_click=form_callback)

序列化是指将对象或数据结构转换为可以持久化和共享的格式,并允许您恢复数据的原始结构的过程。Python的内置pickle模块将Python对象序列化为字节流(“pickling”),并将流反序列化为对象(“unpickling”)。

默认情况下,Streamlit的Session State允许您在会话期间持久化任何Python对象,无论对象是否可pickle序列化。此属性使您可以存储Python基本类型,如整数、浮点数、复数和布尔值,数据框,甚至函数返回的lambdas。然而,某些执行环境可能需要对Session State中的所有数据进行序列化,因此在开发期间检测不兼容性,或当执行环境将来停止支持时,可能会很有用。

为此,Streamlit 提供了一个 runner.enforceSerializableSessionState 配置选项,当设置为 true 时,只允许在 Session State 中使用可 pickle 序列化的对象。要启用此选项,可以创建一个全局或项目配置文件,内容如下,或者将其用作命令行标志:

# .streamlit/config.toml [runner] enforceSerializableSessionState = true

所谓“pickle-serializable”,是指调用pickle.dumps(obj)不应引发PicklingError异常。当启用配置选项时,向会话状态添加不可序列化的数据应导致异常。例如,

import streamlit as st def unserializable_data(): return lambda x: x #👇 results in an exception when enforceSerializableSessionState is on st.session_state.unserializable = unserializable_data()
UnserializableSessionStateError
priority_high

警告

runner.enforceSerializableSessionState设置为true时,Session State隐式使用pickle模块,该模块已知不安全。确保所有从Session State保存和检索的数据都是可信的,因为有可能构造恶意的pickle数据,在反序列化期间执行任意代码。切勿以不安全模式加载可能来自不可信来源的数据,或可能被篡改的数据。仅加载您信任的数据

  • 只有st.form_submit_button在表单中有回调。表单内的其他小部件不允许有回调。

  • on_changeon_click 事件仅在输入类型的小部件上受支持。

  • 在实例化后,通过Session状态API修改小部件的值是不允许的,并且会引发StreamlitAPIException。例如:

    slider = st.slider( label='My Slider', min_value=1, max_value=10, value=5, key='my_slider') st.session_state.my_slider = 7 # 抛出异常!
    state-modified-instantiated-exception
  • 不建议通过会话状态API设置小部件状态并在小部件声明中使用value参数,这将在第一次运行时抛出警告。例如:

    st.session_state.my_slider = 7 slider = st.slider( label='选择一个值', min_value=1, max_value=10, value=5, key='my_slider')
    state-value-api-exception
  • 设置类似按钮的小部件的状态:通过Session State API设置st.buttonst.download_buttonst.file_uploader是不允许的。这类小部件默认是False,并且具有短暂的True状态,这些状态仅对单次运行有效。例如:

    if 'my_button' not in st.session_state: st.session_state.my_button = True st.button('My button', key='my_button') # 抛出异常!
    state-button-exception
forum

还有问题吗?

我们的 论坛 充满了有用的信息和Streamlit专家。