一、什么是st.session_state
会话状态是一种方法,用于在用户的每次会话中共享变量,确保这些变量在重新运行(Rerun)时仍然可用。简单来说,你可以把会话状态想象成一个“状态缓存”,它就像是一个存储箱,可以存放各种对象。
一旦应用初始化完成后,会话状态通常不会被整体重置,即使你重新运行应用,之前的会话状态仍然会保留下来,不会被清除。
既然会话状态是变量,那它就具备了变量的特性。你可以使用各种函数,包括回调函数,来调用或修改它的值。这就像是你有一个可以随意存取和修改内容的存储箱,让你在应用的不同部分之间传递和共享信息变得更加方便和灵活。
当用户成功登录后,系统便会利用session_state来保存其登录状态。这一过程中,回调函数发挥着关键作用,将session_state中的登录状态标记从False转变为True。一旦登录状态被正确记录,用户在后续的所有操作中都将无需再次登录,从而享受到更加流畅和便捷的使用体验。
二、事件与回调
无论是使用哪种GUI库,当用户在通过该库创建的程序中进行操作时,GUI都会密切地监听用户所触发的各类事件。一旦事件被触发,GUI便会立即响应,并自动运行与该事件相对应的回调函数,从而确保程序的顺畅运行和用户的良好体验。这一机制使得GUI库在构建交互式程序时显得尤为高效和灵活。
比如,一个关闭软件窗口的回调函数通常是这样的:
while True:
窗口运行代码
if event == 窗口关闭函数:
break
其他业务代码
这表示,程序在窗口运行时将持续监听所有事件。一旦检测到用户点击了右上角的“X”或发生其他触发窗口关闭的行为,程序将中断当前窗口循环(loop),从而结束窗口的运行。
然而,Streamlit的一个特性使得某些业务逻辑的实现变得棘手:
Streamlit要求用户必须通过互动组件(interactive widgets)来触发回调,并且每次互动组件的操作都会导致整个应用代码重新运行(rerun)。这是Streamlit的一个显著特点,它确保了应用的实时响应性。
(值得注意的是,为减少代码重新运行带来的资源消耗,Streamlit提供了st.cache方法,允许程序忽略部分代码的执行,例如读取内容固定的文件。但这一话题在此不作深入探讨。)
因此,以下业务逻辑由于这一特性的限制而无法直接实现:
Streamlit的特定机制确实限制了某些业务逻辑的实现。具体而言,您想要实现的逻辑如下:
- 触发组件A,执行程序A,并获得返回值A(该值非常量)。
- 使用返回值A来显示组件B。
- 将返回值A作为参数传递给程序B,并期望通过触发组件B来执行该程序。
然而,由于Streamlit的rerun特性,每当触发组件B时,整个应用会重新运行,导致状态回到初始状态。这意味着组件B的内容尚未显示,用户便无法与其交互。
为了解决这个问题,我们可以利用Streamlit的session_state
功能。session_state
允许您在用户会话期间存储和访问状态信息,从而在不同的事件回调之间保持数据的一致性。通过合理使用session_state
,您可以保存之前操作的结果(如返回值A),并在需要时从session_state
中检索它们,以确保程序的逻辑能够按预期执行。