块中的状态

我们介绍了Interfaces 中的 State ,本指南介绍了 Blocks 中的状态,它们的工作原理基本相同。

We covered State in Interfaces, this guide takes a look at state in Blocks, which works mostly the same.

全局状态

Blocks 中的全局状态与 Interface 中的一样。 在函数调用之外创建的任何变量都是所有用户共享的引用。

Global state in Blocks works the same as in Interface. Any variable created outside a function call is a reference shared between all users.

会话状态

Gradio 支持会话状态,其中数据在页面会话中跨多个提交持续存在,在 Blocks 应用程序中也是如此。 重申一下,会话数据不会在模型的不同用户之间共享。 要在会话状态中存储数据,你需要做三件事:

Gradio supports session state, where data persists across multiple submits within a page session, in Blocks apps as well. To reiterate, session data is not shared between different users of your model. To store data in a session state, you need to do three things:

  1. 创建一个 gr.State() 对象。 如果此有状态对象有默认值,请将其传递给构造函数。

    Create a gr.State() object. If there is a default value to this stateful object, pass that into the constructor.

  2. 在事件侦听器中,将 State 对象作为输入和输出。

    In the event listener, put the State object as an input and output.

  3. 在事件侦听器函数中,将变量添加到输入参数和返回值中。

    In the event listener function, add the variable to the input parameters and the return value.

让我们来看一个刽子手游戏。

Let's take a look at a game of hangman.

import gradio as gr

secret_word = "gradio"

with gr.Blocks() as demo:    
    used_letters_var = gr.State([])
    with gr.Row() as row:
        with gr.Column():
            input_letter = gr.Textbox(label="Enter letter")
            btn = gr.Button("Guess Letter")
        with gr.Column():
            hangman = gr.Textbox(
                label="Hangman",
                value="_"*len(secret_word)
            )
            used_letters_box = gr.Textbox(label="Used Letters")

    def guess_letter(letter, used_letters):
        used_letters.append(letter)
        answer = "".join([
            (letter if letter in used_letters else "_")
            for letter in secret_word
        ])
        return {
            used_letters_var: used_letters,
            used_letters_box: ", ".join(used_letters),
            hangman: answer
        }
    btn.click(
        guess_letter, 
        [input_letter, used_letters_var],
        [used_letters_var, used_letters_box, hangman]
        )
demo.launch()

让我们看看我们如何在这个游戏中执行上面列出的 3 个步骤中的每一个:

Let's see how we do each of the 3 steps listed above in this game:

  1. 我们将使用过的字母存储在 used_letters_var 中。 在 State 的构造函数中,我们将 this 的初始值设置为 [] ,一个空列表。

    We store the used letters in used_letters_var. In the constructor of State, we set the initial value of this to [], an empty list.

  2. btn.click() 中,我们在输入和输出中都有对 used_letters_var 引用。

    In btn.click(), we have a reference to used_letters_var in both the inputs and outputs.

  3. guess_letter 中,我们将这个 State 的值传递给 used_letters ,然后在 return 语句中返回这个 State 的更新值。

    In guess_letter, we pass the value of this State to used_letters, and then return an updated value of this State in the return statement.

对于更复杂的应用程序,你可能会在单个 Blocks 应用程序中使用许多状态变量来存储会话状态。

With more complex apps, you will likely have many State variables storing session state in a single Blocks app.

文档中了解有关 State 的更多信息。

Learn more about State in the docs.