こんにちは、JS2IIUです。
Streamlitを使ってアプリケーションを作っていると、「ボタンをクリックしたはずなのに、値がリセットされる」「ページを更新すると入力内容が消える」といった経験をしたことはありませんか?
これは、Streamlitの特性としてスクリプト全体が毎回実行されるためです。この問題を解決するのが、今回ご紹介する st.session_state です。
この機能を使えば、ユーザーの操作に応じた変数の値をセッションごとに保持することができます。今回もよろしくお願いします。
st.session_stateとは?
st.session_stateは、ユーザーごとの状態(State)を記録する辞書のようなオブジェクトです。セッションとは「ユーザーがページを開いてから閉じるまでの間」を指します。
この機能を使うことで、以下のようなことが可能になります:
- ページの更新後も変数の値を保持する
- ボタンを何度クリックしても、前回の値を覚えている
- 複数のページ間で状態を共有する
st.session_stateがないと困ること
例えば、以下のようなコードを考えてみましょう。
import streamlit as st
count = 0
if st.button("カウントアップ"):
count += 1
st.write("現在のカウント:", count)このコードでは、ボタンをクリックしても毎回カウントは「1」に戻ってしまいます。なぜなら、スクリプトが毎回ゼロから実行されるためです。
st.session_stateの基本的な使い方
この問題を解決するには、st.session_stateを使って値を保持します。
🔰 ステップ1:初期化
まず、セッション状態に変数がなければ初期化します。
if 'count' not in st.session_state:
st.session_state.count = 0🛎️ ステップ2:ボタンのクリックで変数を更新
if st.button("カウントアップ"):
st.session_state.count += 1📋 ステップ3:現在の値を表示
st.write("現在のカウント:", st.session_state.count)✅ 完全なコード
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("現在のカウント:", st.session_state.count)実践事例①:ページの再読み込みで値を保持する
フォーム入力などで、再読み込みしても入力を残したい場合に便利です。
import streamlit as st
# セッションに値がなければ初期化
if 'text' not in st.session_state:
st.session_state.text = ""
# テキスト入力
st.session_state.text = st.text_input("名前を入力してください", st.session_state.text)
# 入力内容を表示
st.write("こんにちは、", st.session_state.text, "さん!")
実践事例②:ボタンのクリック回数をカウントする
先ほどの例を少しアレンジして、リセット機能も追加してみましょう。
import streamlit as st
if 'count' not in st.session_state:
st.session_state.count = 0
col1, col2 = st.columns(2)
with col1:
if st.button("+1"):
st.session_state.count += 1
with col2:
if st.button("リセット"):
st.session_state.count = 0
st.write("カウント値:", st.session_state.count)実践事例③:複数ページ間で状態を共有する
Streamlitはマルチページ構成にも対応していますが、st.session_stateを使えばページ間で状態を共有することができます。
🗂️ Home.py
import streamlit as st
if 'user_name' not in st.session_state:
st.session_state.user_name = ""
st.session_state.user_name = st.text_input("あなたの名前", st.session_state.user_name)📄 Page2.py
import streamlit as st
st.write("ようこそ、", st.session_state.get("user_name", "ゲスト"), "さん!")実践事例④:フォーム入力内容を一時保存する
「送信ボタンを押すまで入力を保持したい」といったケースにも役立ちます。
import streamlit as st
if 'form_data' not in st.session_state:
st.session_state.form_data = {"email": "", "message": ""}
with st.form("contact_form"):
st.session_state.form_data["email"] = st.text_input("メールアドレス", st.session_state.form_data["email"])
st.session_state.form_data["message"] = st.text_area("お問い合わせ内容", st.session_state.form_data["message"])
submitted = st.form_submit_button("送信")
if submitted:
st.success("送信が完了しました!")
st.write("内容:", st.session_state.form_data)
よくあるエラーと対処法
| エラー | 原因 | 対処法 |
|---|---|---|
AttributeError: 'count' | 変数が初期化されていない | 'count' not in st.session_state で初期化 |
| 値が保持されない | 値を直接変数に保存している | st.session_state["key"] = 値の形式を使う |
| 値が突然消える | セッションが切れた | キャッシュやCookieの影響、再起動の可能性あり |
まとめ
st.session_stateを使えば、Streamlitの「スクリプト全再実行」の制約を回避できる- 初期化 → 操作 → 表示の流れで使うのが基本
- フォームやナビゲーションなど、実際のアプリ開発において非常に有用
参考リンク
当ブログのst.session_stateに関連する記事も参考にしてください。色々な角度での記事を書いています。よろしくお願いします。
- 【Streamlit】st.session_stateの初期化を関数化して整理する方法 | アマチュア無線局JS2IIU
- 【Streamlit】st.session_state とコールバック関数の活用方法 | アマチュア無線局JS2IIU
- 【Streamlit】st.session_state.clear() による状態のリセット操作 | アマチュア無線局JS2IIU
- 【Streamlit】st.session_state に辞書・リストなどの複雑なオブジェクトを持たせる方法と実践例 | アマチュア無線局JS2IIU
- 【Streamlit】st.session_state でフラグ制御と一時的なUI操作を管理する | アマチュア無線局JS2IIU
- 【Streamlit】セッションごとにユニークなIDや一意の情報を持たせる | アマチュア無線局JS2IIU
- 【Streamlit】st.session_stateの内容を開発中にデバッグ表示する方法 | アマチュア無線局JS2IIU
- 【Streamlit】ページ構成が多いアプリでの状態管理戦略(状態設計のベストプラクティス) | アマチュア無線局JS2IIU
- 【Streamlit】セッションタイムアウトの扱いと注意点(ブラウザの再読込や切断時) | アマチュア無線局JS2IIU
最後まで読んでいただきありがとうございます。


コメント