装饰器将函数转换为可以独立于完整应用程序重新运行的片段。

当用户与片段内创建的输入小部件交互时,Streamlit 只会重新运行该片段,而不是整个应用程序。如果设置了 run_every,Streamlit 还会在会话活动期间按指定的间隔重新运行该片段,即使用户没有与您的应用程序交互。

要从片段内部触发应用程序重新运行,直接调用st.rerun()。要从片段内部触发片段重新运行,调用st.rerun(scope="fragment")。通常,需要从更广泛的应用程序中访问的片段中的任何值应存储在会话状态中。

当在片段中直接调用Streamlit元素命令时,元素会在每次片段重新运行时被清除并重新绘制,就像所有元素在每次应用程序重新运行时都会重新绘制一样。在片段重新运行期间,应用程序的其余部分会被保留。当片段将元素渲染到外部创建的容器中时,元素不会在每次片段重新运行时被清除。相反,元素会在每次片段重新运行时累积在这些容器中,直到下一次应用程序重新运行。

不支持在片段中调用st.sidebar。要在片段中将元素写入侧边栏,请在with st.sidebar上下文管理器中调用您的片段函数。

片段代码可以与Session State、导入的模块以及在片段外部创建的其他Streamlit元素进行交互。请注意,这些交互在多个片段重新运行时是累积的。您需要负责处理该行为可能产生的任何副作用。

警告

  • 片段只能在其主体中包含小部件。片段无法将小部件渲染到外部创建的容器中。
函数签名[source]

st.fragment(func=None, *, run_every=None)

参数

func (callable)

要转换为片段的函数。

run_every (int, float, timedelta, str, 或 None)

自动片段重新运行之间的时间间隔。这可以是以下之一:

  • None(默认)。
  • 一个intfloat,指定以秒为单位的间隔。
  • 一个字符串,指定时间格式,支持Pandas的Timedelta构造函数, 例如"1d""1.5 days",或"1h23s"
  • 一个来自Python内置的datetime库timedelta对象, 例如timedelta(days=1)

如果run_everyNone,片段将仅从用户触发的事件重新运行。

示例

以下示例演示了@st.fragment的基本用法。作为一个类比,“充气球”是一个在片段外部发生的缓慢过程。“释放气球”是一个在片段内部发生的快速过程。

import streamlit as st
import time

@st.fragment
def release_the_balloons():
    st.button("Release the balloons", help="Fragment rerun")
    st.balloons()

with st.spinner("Inflating balloons..."):
    time.sleep(5)
release_the_balloons()
st.button("Inflate more balloons", help="Full rerun")

下一个示例演示了在每次应用程序或片段重新运行时,片段内部和外部的元素如何相互更新。在这个应用程序中,点击“重新运行完整应用程序”将增加两个计数器并更新应用程序中显示的所有值。相比之下,点击“重新运行片段”只会增加片段内的计数器。在这种情况下,片段内的st.write命令将更新应用程序的前端,但片段外的两个st.write命令不会更新前端。

import streamlit as st

if "app_runs" not in st.session_state:
    st.session_state.app_runs = 0
    st.session_state.fragment_runs = 0

@st.fragment
def my_fragment():
    st.session_state.fragment_runs += 1
    st.button("Rerun fragment")
    st.write(f"Fragment says it ran {st.session_state.fragment_runs} times.")

st.session_state.app_runs += 1
my_fragment()
st.button("Rerun full app")
st.write(f"Full app says it ran {st.session_state.app_runs} times.")
st.write(f"Full app sees that fragment ran {st.session_state.fragment_runs} times.")

你也可以通过调用st.rerun从片段内部触发应用程序的重新运行。

import streamlit as st

if "clicks" not in st.session_state:
    st.session_state.clicks = 0

@st.fragment
def count_to_five():
    if st.button("Plus one!"):
        st.session_state.clicks += 1
        if st.session_state.clicks % 5 == 0:
            st.rerun()
    return

count_to_five()
st.header(f"Multiples of five clicks: {st.session_state.clicks // 5}")

if st.button("Check click count"):
    st.toast(f"## Total clicks: {st.session_state.clicks}")
forum

还有问题吗?

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