【Streamlit】st.session_state.clear() による状態のリセット操作

Streamlit
この記事は約19分で読めます。

こんにちは、JS2IIUです。
Streamlitでアプリを作っていると、ユーザーの操作に応じて状態(state)を保持したり、必要に応じてそれをリセットしたい場面がよくあります。本記事では、st.session_state.clear() を使った状態のリセット方法と、特定のキーだけを削除する del の使い分けについて、実例を交えてわかりやすく解説します。

1. session_stateとは?

Streamlitでは、ボタンが押されたかどうかや、入力された値などをセッション間で保持するために st.session_state が使えます。これにより、例えばボタンを押すたびにカウントアップするようなアプリが作れます。

Python
import streamlit as st

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

if st.button("カウントアップ"):
    st.session_state.count += 1

st.write(f"現在のカウント: {st.session_state.count}")

このように、st.session_state に値を保存しておくことで、アプリ内で状態を持たせることができます。

2. 状態をリセットする方法

状態をリセットする方法は大きく2つあります。

2-1. st.session_state.clear():すべてを初期化

すべてのキーと値をまとめて削除します。

Python
if st.button("すべてリセット"):
    st.session_state.clear()
    st.experimental_rerun()  # 初期状態に再読み込み

この方法はログアウトやアプリ全体のリセットに便利です。

2-2. del st.session_state["key"]:特定のキーだけを削除

必要なキーだけを削除したい場合はこちらを使います。

Python
if st.button("カウントだけリセット"):
    if "count" in st.session_state:
        del st.session_state["count"]
    st.experimental_rerun()

delを使えば、他の状態を維持しながら特定の値だけを初期化できます

3. 実例:ログイン・ログアウトの実装

ここでは簡単なログイン・ログアウトの例を紹介します。

Python
import streamlit as st

def login():
    username = st.text_input("ユーザー名")
    if st.button("ログイン"):
        if username:
            st.session_state.user = username
        else:
            st.warning("ユーザー名を入力してください")

def main_app():
    st.write(f"ようこそ、{st.session_state.user}さん!")
    if st.button("ログアウト"):
        st.session_state.clear()
        st.rerun()

if "user" in st.session_state:
    main_app()
else:
    login()

ログイン時に user を保存し、ログアウト時に clear() で全リセット。再読み込みでログイン画面に戻ります。

詳細解説

1. ライブラリの読み込み

Python
import streamlit as st

Streamlit の機能を使うために streamlit モジュールを読み込みます。

2. login() 関数:ログイン画面を表示

Python
def login():
    username = st.text_input("ユーザー名")
  • ユーザーに名前を入力してもらうためのテキスト入力フィールドを表示します。
  • 入力値は username に格納されます。
Python
    if st.button("ログイン"):
        if username:
            st.session_state.user = username
        else:
            st.warning("ユーザー名を入力してください")
  • 「ログイン」ボタンがクリックされたら処理を開始します。
  • ユーザー名が入力されている場合は st.session_state["user"] に値を保存します。
  • 入力されていなければ警告メッセージを表示します。

ポイント:
st.session_state は辞書のように使えるため、ここでは user というキーでユーザー名を保存しています。これにより他の関数でもログイン状態が参照できるようになります。

3. main_app() 関数:ログイン後の画面を表示

Python
def main_app():
    st.write(f"ようこそ、{st.session_state.user}さん!")
  • 保存されている user の値(ユーザー名)を使って、歓迎メッセージを表示します。
Python
    if st.button("ログアウト"):
        st.session_state.clear()
        st.rerun()
  • 「ログアウト」ボタンがクリックされたら:
  • st.session_state.clear()すべての状態を初期化 します。
  • st.rerun() でアプリをリロードし、ログイン画面に戻します。

ポイント:

  • clear() を使うことで、ログイン状態(userキー)だけでなく他のキーも含めて初期化されます。
  • rerun() をしないとログイン中の画面がそのまま残ってしまうため、忘れずに呼び出しましょう。

4. 実行部分:状態によって表示を切り替える

Python
if "user" in st.session_state:
    main_app()
else:
    login()
  • st.session_state"user" キーが存在するかをチェックして、
  • ログイン済みなら main_app() を表示。
  • まだログインしていないなら login() を表示。

全体の流れまとめ

操作動作内容
ユーザー名入力 → 「ログイン」クリックsession_state.user に名前を保存
ログイン状態で画面表示「ようこそ〇〇さん」と表示
「ログアウト」クリック状態を全削除 → 画面をリロードしログイン画面に戻る

補足:ログアウト時に一部の状態だけ保持したい場合

もしログアウト時にユーザー名だけリセットしたい場合は clear() の代わりに以下のように del を使います:

Python
del st.session_state["user"]
st.experimental_rerun()

このように del を使えば、他の状態はそのまま残しつつ、特定のキーだけをリセットできます。

4. 実例:入力フォームとリセットボタン

Python
import streamlit as st

def show_form():
    st.text_input("名前", key="name")
    st.text_area("メッセージ", key="message")

    if st.button("送信"):
        st.success("送信されました!")
        st.session_state.submitted = True

    if st.button("リセット"):
        for key in ["name", "message", "submitted"]:
            if key in st.session_state:
                del st.session_state[key]
        st.rerun()

show_form()

必要なキーだけを del で削除することで、他のセッション情報を保ったままフォームだけをリセットできます。

詳細解説

1. ライブラリのインポート

Python
import streamlit as st
  • StreamlitのAPIを使うためにインポートします。

2. 入力フォームの表示

Python
st.text_input("名前", key="name")
st.text_area("メッセージ", key="message")
  • st.text_input:一行テキスト入力欄(名前)
  • st.text_area:複数行の入力欄(メッセージ)

どちらも key を指定しているため、値は st.session_state["name"]st.session_state["message"] として保存されます。

3. 「送信」ボタン

Python
if st.button("送信"):
    st.success("送信されました!")
    st.session_state.submitted = True
  • ボタンが押されると「送信されました!」という成功メッセージを表示します。
  • 送信済み状態を保持するために、st.session_state.submitted = True を設定します。

これにより、アプリが「送信済み」であることを記憶できます。

4. 「リセット」ボタン

Python
if st.button("リセット"):
    for key in ["name", "message", "submitted"]:
        if key in st.session_state:
            del st.session_state[key]
    st.rerun()

処理の流れ:

  1. 「リセット」ボタンが押されると、
  2. st.session_state から "name", "message", "submitted" の各キーを削除します。
  3. st.rerun() によってアプリを再実行(=初期状態に戻す)します。

この仕組みで、フォームが空の状態に戻るようになります。

✨ このコードのポイントまとめ

処理内容使用された関数説明
入力の保持st.text_input, st.text_area(+key入力値がセッションに保存される
送信ボタンst.button + st.success + session_stateフォーム送信と送信状態の保持
リセット処理del session_state[...] + st.rerun()特定キーを削除して再実行(初期化)

5. 実例:ショッピングカートの初期化

ECサイトのようなアプリで、ユーザーの買い物かご(カート)をリセットする例です。

Python
import streamlit as st

if "cart" not in st.session_state:
    st.session_state.cart = []

st.write("現在のカート:", st.session_state.cart)

if st.button("商品を追加"):
    st.session_state.cart.append("商品A")

if st.button("カートをリセット"):
    del st.session_state["cart"]
    st.rerun()

このように、カートだけを del で初期化すれば、ログイン情報など他の情報は維持されます。

詳細解説

このコードは、Streamlitで「ショッピングカート」のような簡単なリストを扱う状態管理の例です。
ユーザーが「商品を追加」ボタンを押すとカートに「商品A」が追加され、「カートをリセット」ボタンでカートの内容を初期化(削除)します。

1. ライブラリのインポート

Python
import streamlit as st

Streamlitライブラリをstという名前でインポートします。これにより、Streamlitの各種関数をst.で呼び出せます。

2. st.session_state.cartの初期化

Python
if "cart" not in st.session_state:
    st.session_state.cart = []

セッション状態(st.session_state)に「cart」というキーが存在しない場合の処理です。アプリが初回起動されたときや、カートがリセットされた直後が該当します。上記の条件が真の場合、cart というキーに空のリスト([])をセットし、カートを初期化します。

3. カートの中身を表示する

Python
st.write("現在のカート:", st.session_state.cart)`

現在のカートの中身を画面に表示します。

4. カートに商品を追加する

Python
if st.button("商品を追加"):
    st.session_state.cart.append("商品A")

「商品を追加」ボタンが押されたかをチェックします。ボタンが押されていれば、cart リストに "商品A" を追加します。

5. カートをリセットする

Python
if st.button("カートをリセット"):`
    del st.session_state["cart"]
    st.rerun()

「カートをリセット」ボタンが押されたかをチェックします。カートの情報(cartキー)だけを削除します。これにより、次回の再描画時に再び空のカートが生成されます。
削除した直後に st.rerun() を呼び出すことで、アプリ全体を再実行し、状態を初期状態に戻します(cartが存在しない → 空リストに再初期化)。

動作フローまとめ

  1. 起動時に cart がなければ空のリストに初期化。
  2. 「商品を追加」ボタンで "商品A"cart に追加。
  3. 「カートをリセット」ボタンで cart を削除 → 再実行で初期状態に。

6. 実例:クイズのリスタート機能

クイズアプリで、再挑戦したいときに全ての状態をリセットする例です。

Python
import streamlit as st

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

st.write(f"スコア: {st.session_state.score}")

if st.button("正解を選択"):
    st.session_state.score += 1

if st.button("もう一度チャレンジ"):
    st.session_state.clear()
    st.rerun()

スコアや選択状態をすべてリセットして、初期画面に戻すことができます。

コードの解説

  • if "score" not in st.session_state:
    初回実行時や状態がリセットされた後に、スコア用の初期値(0)を設定します。
  • st.write(f"スコア: {st.session_state.score}")
    現在のスコアを画面上に表示します。
  • if st.button("正解を選択"):
    「正解を選択」ボタンが押されたとき、スコアを1加算します。
  • if st.button("もう一度チャレンジ"):
    このボタンが押された場合、st.session_state.clear() によってすべてのセッション状態(今回の場合は score)を削除し、st.experimental_rerun() によって初期状態から再描画します。

実行結果のイメージ

  1. アプリ起動直後は「スコア: 0」と表示。
  2. 「正解を選択」ボタンを押すたびに、スコアが1ずつ加算されます。
  3. 「もう一度チャレンジ」ボタンを押すと、スコアが0に戻り、再チャレンジ可能な状態になります。

このように、クイズやテスト形式のアプリで、スコアの初期化と再スタートの処理をシンプルに実装することができます。

7. 実例:一時的な通知のリセット

通知メッセージなどを一時的に表示し、一定操作後に消したい場合に有効です。

Python
import streamlit as st

if st.button("通知を表示"):
    st.session_state.notice = "このメッセージは一時的に表示されます"

if "notice" in st.session_state:
    st.info(st.session_state.notice)
    if st.button("通知を消す"):
        del st.session_state["notice"]
        st.rerun()

特定のキーだけを削除することで、通知のみを取り除く処理が可能です。

各部分の解説

1. st.button("通知を表示")

  • このボタンが押されると、st.session_state.notice に通知メッセージ(今回は「このメッセージは一時的に表示されます」)を保存します。
  • st.session_state を使うことで、通知の状態を維持できます。

2. if "notice" in st.session_state:

  • notice というキーがセッション状態に存在するかどうかを確認します。
  • 存在する(つまり通知がある)場合にのみ、メッセージを表示する処理を実行します。

3. st.info(st.session_state.notice)

  • st.info() は Streamlit に用意されている情報メッセージ表示用のUI部品です。
  • セッションに保存されている通知メッセージを表示します。

4. if st.button("通知を消す"):

  • 「通知を消す」ボタンが押されると、セッション状態から notice キーを削除します。

5. del st.session_state["notice"]

  • notice というキーとその値をセッション状態から完全に削除します。
  • これにより次回の再描画で if "notice" in st.session_state:False になり、メッセージは表示されません。

6. st.experimental_rerun()

  • 削除後にアプリを再実行して、画面を初期状態に更新します。
  • これにより「通知を消す」ボタンを押すとすぐに通知が非表示になります。

実行イメージの流れ

  1. 起動時:通知は表示されていない。
  2. 「通知を表示」ボタンをクリック → メッセージが表示され、「通知を消す」ボタンも現れる。
  3. 「通知を消す」ボタンをクリック → メッセージとボタンが両方消える。

8. まとめ

  • st.session_state.clear() はすべての状態をリセットする
  • del st.session_state["key"] は個別にリセットできる
  • 状況に応じて使い分けることで、より柔軟で使いやすいアプリを実現できる
  • 状態をリセットした後は st.experimental_rerun() を併用することで、初期状態に戻すことができる

参考リンク

最後まで読んでいただきありがとうございます。

コメント

タイトルとURLをコピーしました