重要
这是一个实验性功能。实验性功能及其API可能会随时更改或删除。要了解更多信息,请点击这里。
示例
在下面的示例中,按下“清除所有”按钮将清除所有单例缓存。即清除所有使用@st.experimental_singleton装饰的函数中的缓存单例对象。
import streamlit as st
from transformers import BertModel
@st.experimental_singleton
def get_database_session(url):
# Create a database session object that points to the URL.
return session
@st.experimental_singleton
def get_model(model_type):
# Create a model of the specified type.
return BertModel.from_pretrained(model_type)
if st.button("Clear All"):
# Clears all singleton caches:
st.experimental_singleton.clear()
Validating the cache
@st.experimental_singleton 装饰器用于缓存函数的输出,以便它只需要执行一次。这可以在某些情况下提高性能,例如当函数需要很长时间执行或进行网络请求时。
然而,在某些情况下,缓存的输出可能会随着时间的推移而失效,例如当数据库连接超时时。为了处理这种情况,@st.experimental_singleton 装饰器支持一个可选的 validate 参数,该参数接受一个验证函数,每次访问缓存输出时都会调用该函数。如果验证函数返回 False,缓存的输出将被丢弃,并再次执行装饰的函数。
Best Practices
- 当缓存输出可能随时间变得无效时,例如当数据库连接或API密钥过期时,使用
validate参数。 - 谨慎使用
validate参数,因为它会在每次访问缓存输出时增加调用验证函数的额外开销。 - 确保验证函数尽可能快,因为每次访问缓存输出时都会调用它。
- 考虑定期验证缓存数据,而不是每次访问时都验证,以减轻性能影响。
- 处理在验证过程中可能发生的错误,并在验证失败时提供回退机制。
Replay static st elements in cache-decorated functions
使用@st.experimental_singleton装饰的函数可以包含静态的st元素。当执行一个缓存装饰的函数时,我们会记录生成的元素和块消息,因此即使由于结果被缓存而跳过函数的执行,这些元素也会出现在应用程序中。
在下面的示例中,@st.experimental_singleton 装饰器用于缓存 get_model 函数的执行,该函数返回一个 🤗 Hugging Face Transformers 模型。请注意,缓存的函数还包含一个 st.bar_chart 命令,当函数因为结果被缓存而被跳过时,该命令将被重放。
import numpy as np
import pandas as pd
import streamlit as st
from transformers import AutoModel
@st.experimental_singleton
def get_model(model_type):
# Contains a static element st.bar_chart
st.bar_chart(
np.random.rand(10, 1)
) # This will be recorded and displayed even when the function is skipped
# Create a model of the specified type
return AutoModel.from_pretrained(model_type)
bert_model = get_model("distilbert-base-uncased")
st.help(bert_model) # Display the model's docstring

支持的静态 st 元素在缓存装饰函数中包括:
st.alertst.altair_chartst.area_chartst.audiost.bar_chartst.ballonsst.bokeh_chartst.captionst.codest.components.v1.htmlst.components.v1.iframest.containerst.dataframest.echost.emptyst.errorst.exceptionst.expanderst.experimental_get_query_paramsst.experimental_set_query_paramsst.formst.form_submit_buttonst.graphviz_chartst.helpst.imagest.infost.jsonst.latexst.line_chartst.markdownst.metricst.plotly_chartst.progressst.pydeck_chartst.snowst.spinnerst.successst.tablest.textst.vega_lite_chartst.videost.warning
Replay input widgets in cache-decorated functions
除了静态元素外,使用@st.experimental_singleton装饰的函数也可以包含输入小部件!默认情况下,重放输入小部件是禁用的。要启用它,您可以将@st.experimental_singleton的experimental_allow_widgets参数设置为True。下面的示例启用了小部件重放,并展示了在缓存装饰函数中使用复选框小部件的情况。
import streamlit as st
# Enable widget replay
@st.experimental_singleton(experimental_allow_widgets=True)
def func():
# Contains an input widget
st.checkbox("Works!")
func()
如果缓存装饰的函数包含输入小部件,但experimental_allow_widgets设置为False或未设置,Streamlit将抛出CachedStFunctionWarning,如下所示:
import streamlit as st
# Widget replay is disabled by default
@st.experimental_singleton
def func():
# Streamlit will throw a CachedStFunctionWarning
st.checkbox("Doesn't work")
func()

How widget replay works
让我们揭开缓存装饰函数中小部件重放的神秘面纱,并对其概念有一个理解。小部件的值被视为函数的额外输入,并用于确定是否应执行该函数。考虑以下示例:
import streamlit as st
@st.experimental_singleton(experimental_allow_widgets=True)
def plus_one(x):
y = x + 1
if st.checkbox("Nuke the value 💥"):
st.write("Value was nuked, returning 0")
y = 0
return y
st.write(plus_one(2))
plus_one 函数接受一个整数 x 作为输入,并返回 x + 1。该函数还包含一个复选框小部件,用于“清除” x 的值。即 plus_one 的返回值取决于复选框的状态:如果选中,函数返回 0,否则返回 3。
为了知道缓存应该返回哪个值(在缓存命中的情况下),Streamlit 将复选框状态(选中/未选中)视为函数 plus_one 的额外输入(就像 x 一样)。如果用户选中复选框(从而改变其状态),我们会在缓存中查找相同的 x 值(2)和相同的复选框状态(选中)。如果缓存包含此输入组合的值,我们则返回它。否则,我们执行函数并将结果存储在缓存中。
现在让我们了解启用和禁用小部件重放如何改变函数的行为。
Widget replay disabled
- 缓存函数中的小部件会抛出
CachedStFunctionWarning并被忽略。 - 缓存函数中的其他静态元素按预期回放。
Widget replay enabled
- 缓存函数中的小部件不会导致警告,并且会按预期重放。
- 在缓存函数中与小部件交互将导致函数再次执行,并更新缓存。
- 缓存函数中的小部件在重新运行时保持其状态。
- 每个小部件值的唯一组合被视为函数的单独输入,并用于确定是否应执行该函数。即每个小部件值的唯一组合都有自己的缓存条目;缓存的函数在第一次运行时执行,之后使用保存的值。
- 在一个脚本运行中多次调用具有相同参数的缓存函数会触发
DuplicateWidgetID错误。 - 如果缓存函数的参数发生变化,从该函数重新渲染的小部件将保留其状态。
- 更改缓存函数的源代码会使缓存失效。
- 无论是
st.experimental_singleton还是st.experimental_memo都支持小部件重放。 - 基本上,当函数被
@st.experimental_singleton或@st.experimental_memo装饰时,其中包含(支持的)小部件的函数的行为不会改变。唯一的区别是,只有在检测到缓存“未命中”时才会执行该函数。
Supported widgets
所有输入小部件都支持在缓存装饰的函数中使用。以下是支持的小部件的详尽列表:
st.buttonst.camera_inputst.checkboxst.color_pickerst.date_inputst.download_buttonst.file_uploaderst.multiselectst.number_inputst.radiost.selectboxst.select_sliderst.sliderst.text_areast.text_inputst.time_input
还有问题吗?
我们的 论坛 充满了有用的信息和Streamlit专家。