Streamlit中cache_data装饰函数无法显示进度条的求助
问题原因
st.cache_data装饰的函数会在隔离环境中执行,其内部的Streamlit组件调用不会被渲染到页面——缓存机制仅关注函数的返回值,而非UI输出。旧版st.cache的suppress_st_warning参数在st.cache_data中已移除,无法通过该参数绕过限制。
解决方案
方案一:分离缓存逻辑与进度条展示(推荐,稳定)
将耗时计算的核心逻辑封装为缓存函数,进度条放在主流程中,仅当缓存未命中时显示进度条并执行计算。既保证缓存复用,又能正常展示进度。
示例代码:
import streamlit as st from time import sleep # 缓存核心计算逻辑,仅返回结果 @st.cache_data(show_spinner=False) def heavy_computation(): total = 100 cur = 0 while cur < total: sleep(0.05) cur += 1 return "计算完成" def progress_generator(total_steps): # 生成进度更新,同步计算过程的进度反馈 cur = 0 while cur < total_steps: sleep(0.05) cur += 1 yield cur / total_steps, f"{cur} / {total_steps}" yield 1.0, "计算完成" ### Main ### st.set_page_config(page_title="Test Progress In Cache Function", page_icon=":bar_chart:",layout="wide") st.title(" :bar_chart: Test") # 用会话状态判断是否已缓存结果,避免重复显示进度条 if "computed_result" not in st.session_state: my_bar = st.progress(0.0, text="0 / 100") # 显示进度条的同时触发计算(首次调用会写入缓存) for progress, text in progress_generator(100): my_bar.progress(progress, text=text) # 将缓存结果存入会话状态 st.session_state["computed_result"] = heavy_computation() my_bar.empty() # 展示最终结果 st.text(st.session_state["computed_result"]) st.text('Test Finish')
说明:可进一步抽离heavy_computation和progress_generator的公共循环逻辑,避免代码重复。
方案二:使用实验性参数(不推荐,仅临时测试)
Streamlit提供experimental_allow_widgets参数,允许缓存函数内部使用UI组件,但该参数为实验性特性,可能在未来版本被移除,跨会话使用时易出现异常。
修改原代码如下:
import streamlit as st from time import sleep # 添加experimental_allow_widgets=True参数 @st.cache_data(show_spinner=False, experimental_allow_widgets=True) def showProgressBar(): cur = 0 total = 100 my_bar = st.progress(cur / total, text = "%d / %d" % (cur, total)) while cur < total: sleep(0.05) cur = cur + 1 my_bar.progress(cur / total, text = "%d / %d" % (cur, total)) my_bar.empty() ### Main ### st.set_page_config(page_title="Test Progress In Cache Function", page_icon=":bar_chart:",layout="wide") st.title(" :bar_chart: Test") showProgressBar() st.text('Test Finish')
内容的提问来源于stack exchange,提问作者Eric Sun
相关产品推荐
相关产品推荐

