python项目实战09-AI智能伴侣(ai_partner_1)
st.session_state就像一个“魔法字典”,它存储的数据会在整个会话期间保留下来,即使脚本反复重运行,数据也不会丢失。可以把它想象成一个应用的“记忆体”,让应用能够“记住”用户的选择和状态。这意味着,虽然你用了OpenAI的库,但你的请求实际上会被发送到DeepSeek的服务器,而不是OpenAI的服务器。)进行对话的“通行证”和“连接器”。这段代码通常用于替代 OpenAI 的官方 S
1.streamlit测试
2.文件操作
(1) 读取文件
# 读文件
# 1. 打开文件
f = open("resources/望庐山瀑布.txt","r",encoding="utf-8")
# 法一:读取文件内容
# content= f.read();
# print(content)
# 法二:逐行读取
content_list = f.readlines()
# line.strip()作用:去除字符串“首尾”两端的空白字符
for line in content_list:
print(line.strip())
# 3. 关闭文件
f.close()
(2) 写文件
# 写文件
# 1. 打开文件
f = open("resources/静夜思.txt","w",encoding="utf-8")
# 2. 写入文件内容
f.write("静夜思(李白)\n\n")
f.write("窗前明月光,\n")
f.write("疑是地上霜。\n")
f.write("举头望明月,\n")
f.write("低头思故乡。\n")
# 3. 关闭文件
f.close()
(3) 释放资源---方式一
# 写文件
# 1. 打开文件
f = open("resources/静夜思.txt","w",encoding="utf-8")
try:
# 2. 写入文件内容
f.write("静夜思(李白)\n\n")
f.write("窗前明月光,\n")
i = 1 / 0
f.write("疑是地上霜。\n")
f.write("举头望明月,\n")
f.write("低头思故乡。\n")
finally:
print("关闭文件")
# 3. 关闭文件
f.close()
(4) 释放资源---方式二(最佳实践)
# 写文件
# 1. 打开文件
with open("resources/静夜思.txt","w",encoding="utf-8") as f:
# 2. 写入文件内容
f.write("静夜思(李白)\n\n")
f.write("窗前明月光,\n")
f.write("疑是地上霜。\n")
f.write("举头望明月,\n")
f.write("低头思故乡。\n")
3.json模块入门
(1) 写入json数据文件
import json
# 写入json数据文件
user = {
"name": "小甜甜",
"age": 18,
"gender": "女",
"hobbies": ["reading", "swimming"]
}
with open("resources/user.json","w",encoding="utf-8") as f:
json.dump(user,f,ensure_ascii=False,indent=2)
(2) 读取json数据文件
# 读取json数据文件
with open("resources/user.json","r",encoding="utf-8") as f:
user = json.load(f)
print(user)
print(type(user))
4.ai_partner_1
代码:
import streamlit as st
import os
from openai import OpenAI
print("----------> 重新执行此文件 , 渲染展示页面")
# 设置页面的配置项
st.set_page_config(
page_title="AI智能伴侣",
page_icon="🤖",
# 布局
layout="wide",
# 控制的是侧边栏的状态
initial_sidebar_state="expanded",
menu_items={}
)
# 大标题
st.title("AI智能伴侣")
# Logo
st.logo("py_project02/resources/logo.png")
# 系统提示词
system_prompt = "你是一名非常可爱的AI助理, 你的名字叫小甜甜, 请你使用温柔可爱的语气回答用户的问题"
# 初始化聊天信息
if "messages" not in st.session_state:
st.session_state.messages = []
# 展示聊天信息
for message in st.session_state.messages: # {"role": "user", "content": prompt}
st.chat_message(message["role"]).write(message["content"])
# 创建与AI大模型交互的客户端对象 (DEEPSEEK_API_KEY 环境变量的名字, 值就是DeepSeek的API_KEY的)
client = OpenAI(api_key=os.environ.get('DEEPSEEK_API_KEY'), base_url="https://api.deepseek.com")
# 消息输入框
prompt = st.chat_input("请输入您要问的问题")
if prompt: # 字符串会自动转换为布尔值, 如果字符串非空, 则为True; ""否则为False
st.chat_message("user").write(prompt)
print("----------> 调用AI大模型, 提示词: ", prompt)
# 保存用户输入的提示词
st.session_state.messages.append({"role": "user", "content": prompt})
# 调用AI大模型
response = client.chat.completions.create(
model="deepseek-chat",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": prompt},
],
stream=False
)
# 输出大模型返回的结果
print("<---------- 大模型返回的结果: ", response.choices[0].message.content)
st.chat_message("assistant").write(response.choices[0].message.content)
# 保存大模型返回的结果
st.session_state.messages.append({"role": "assistant", "content": response.choices[0].message.content})
(1)st.set_page_config()
在使用 st.set_page_config() 时,有一条绝对规则:它必须是你的 Streamlit 脚本中第一个出现的 Streamlit 命令。如果把它放在 st.title()、st.write() 甚至 st.sidebar 之后,程序会报错。

(2) st.session_state
st.session.state是 streamlit 中用于在用户会话期间持久化存储数据的核心机制。要理解它的作用,首先需要明白 streamlit 的一个核心运行机制:每次用户与应用的交互(如点击按钮、选择下拉菜单)都会触发整个脚本从头到尾重新运行。这意味着,普通的 python 变量在每次交互后都会被重置。st.session_state就像一个“魔法字典”,它存储的数据会在整个会话期间保留下来,即使脚本反复重运行,数据也不会丢失。可以把它想象成一个应用的“记忆体”,让应用能够“记住”用户的选择和状态。
主要作用:
1)保持用户状态
这是最常见的作用。例如,记录用户是否已登录、在多步骤表单中保存用户上一步的输入、记住用户选择的语言等。
2)实现计数器
这是理解 st.session_state最经典的例子。
错误示范 (使用普通变量):
import streamlit as st
count = 0 # 每次交互后都会被重置为0
st.write(f"计数: {count}")
if st.button("增加"):
count += 1
在这个例子中,无论点击多少次按钮,计数永远是 1。因为点击按钮后,脚本重跑,count又被初始化为 0 了。
注意:st.button("增加") 的作用是创建一个标签为“增加”的按钮。
它的核心工作机制如下:
- 触发重运行 (Re-run):Streamlit 应用的脚本是自上而下执行的。每当用户与页面上的任何组件(包括按钮)进行交互时,整个 Python 脚本都会从头到尾重新运行一次。
- 返回布尔值:
st.button()函数会返回一个布尔值。- 如果用户刚刚点击了这个按钮,它会返回
True。 - 在其他情况下(例如页面首次加载,或点击了其他组件导致重运行),它会返回
False。
- 如果用户刚刚点击了这个按钮,它会返回
正确示范 (使用st.session_state):
import streamlit as st
# 1. 初始化:检查键是否存在,不存在则创建
if 'count' not in st.session_state:
st.session_state.count = 0
st.write(f"计数: {st.session_state.count}")
# 2. 修改:在回调函数或直接操作中修改
if st.button("增加"):
st.session_state.count += 1
现在,每次点击按钮,计数都会正确地累加。
3)防止重复提交和操作锁定
在执行耗时操作(如加载大数据、调用AI模型)时,可以使用 session_state设置一个“锁”,防止用户多次点击按钮导致程序重复执行或崩溃。
if 'is_processing' not in st.session_state:
st.session_state.is_processing = False
if st.button("开始处理") and not st.session_state.is_processing:
st.session_state.is_processing = True # 上锁
# ... 执行耗时操作 ...
st.session_state.is_processing = False # 解锁
4)跨页面传递数据
在多页面应用(Multi-page App)中, st.session_state是在不同页面间共享和传递数据的理想工具。例如,用户在首页选择的参数,可以在结果页中读取和使用。
st.session_state的使用方式非常像一个 Python 字典。
基本用法
1)初始化
在使用任何 session_state 变量前,最好先检查它是否存在,并设置一个默认值。这通常在脚本的开头进行。
if 'user_name' not in st.session_state:
st.session_state.user_name = ''
if 'login_status' not in st.session_state:
st.session_state.login_status = False
2)赋值与读取
# 赋值
st.session_state['my_key'] = 'some_value'
st.session_state.my_key = 'some_value' # 也可以用点号访问
# 读取
name = st.session_state['user_name']
status = st.session_state.login_status
3)与组件组合
许多 Streamlit 组件(如 st.text_input, st.checkbox)都有一个 key 参数。当设置了 key 后,组件的值会自动与 st.session_state 中对应键的值同步。
st.text_input("你的名字", key="name_input")
# 可以直接通过 session_state 获取输入框的值
st.write(f"你好, {st.session_state.name_input}")
注意:
1)数据生命周期:st.session_state 中的数据在用户的浏览器标签页关闭或会话超时后会被清除。
2)服务器端存储:session_state 的数据存储在服务器内存中。如果应用用户量巨大,需要留意服务器的内存使用情况。
3)与缓存(@st.cache_data)的区别:
st.session_state用于存储用户特定的、易变的状态(如登录信息、表单输入)。@st.cache_data用于缓存耗时的、不变的计算结果或数据加载(如读取大型CSV文件、训练好的模型),以提升所有用户的访问性能。
(3)st.chat_message
st.chat_message 是一个专门用于构建对话式应用(如聊天机器人、AI 助手)的核心组件。简单来说,它的作用是创建一个“气泡”容器,用来展示单条聊天消息。
核心功能与作用:
- 视觉区分:它会根据你指定的角色(
name参数),自动渲染不同的样式。例如,"user"通常显示在右侧(或带有人像图标),而"assistant"显示在左侧(或带有机器人图标)。 - 内容容器:它不仅仅能显示文字。在这个容器内部,你可以放入任何 Streamlit 支持的元素,比如 Markdown 文本、代码块、图表(
st.bar_chart)、图片甚至数据表格。 - 上下文管理:通常配合
with语句使用,表示“在这个消息气泡里,我要放入以下内容”。
import streamlit as st
# 1. 显示用户的消息(通常靠右,带人像图标)
with st.chat_message("user"):
st.write("你好,请问今天天气如何?")
# 2. 显示助手的消息(通常靠左,带机器人图标)
with st.chat_message("assistant"):
st.write("今天天气晴朗,气温适宜!")
st.bar_chart([1, 2, 3]) # 甚至可以放图表
注意:
如果你只是写 st.chat_message,你会发现页面刷新后消息就不见了。这是因为 Streamlit 的脚本是“无状态”的,每次交互(比如输入新消息)都会导致整个脚本从头重跑,变量会被重置。必须配合st.session_state使用,为了记住聊天历史,你需要把每一条消息存进st.session_state列表,并在页面加载时遍历显示它们

import streamlit as st
st.title("💬 我的聊天机器人")
# 1. 初始化聊天历史(如果还没初始化)
if "messages" not in st.session_state:
st.session_state.messages = []
# 2. 遍历历史消息并显示在界面上
# 这是关键!每次页面重跑,都会把存下来的历史记录重新画一遍
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# 3. 处理用户的新输入
if prompt := st.chat_input("说点什么..."):
# A. 显示并保存用户的消息
with st.chat_message("user"):
st.markdown(prompt)
st.session_state.messages.append({"role": "user", "content": prompt})
# B. 模拟助手回复(实际开发中这里会调用 API)
response = f"我收到了你的消息:{prompt}"
with st.chat_message("assistant"):
st.markdown(response)
st.session_state.messages.append({"role": "assistant", "content": response})
(4)调用API
client = OpenAI(api_key=os.environ.get('DEEPSEEK_API_KEY'), base_url="https://api.deepseek.com")什么意思
这行代码的作用是创建一个连接到 DeepSeek 大模型 API 的客户端(Client)对象。简单来说,这是让你的 Python 程序能够“说话”并调用 DeepSeek(深度求索)模型(如 deepseek-chat)进行对话的“通行证”和“连接器”。这段代码通常用于替代 OpenAI 的官方 SDK,因为它使用了 OpenAI 的 Python 库语法,但将请求转发到了 DeepSeek 的服务器地址
1.client:这是你创建的变量名,用来存储这个连接对象。之后你就可以用client来发送请求
2.openAI(...):
(1)这是OenAI官方Python SDK(openai库)提供的一个类
(2)虽然名字叫OpenAI,但因为DeepSeek的API接口兼容OpenAI的协议,所以我们可以"借用"这个类来连接DeepSeek
参数设置:
1.api_key:你的密钥。代码中使用了os.environ.get('DEEPSEEK_API_KEY'),意思是去环境变量中读取名为DEEPSEEK_API_KEY的值。这是一种安全做法,避免将密钥直接写在代码里暴露出去
2.base_url:服务器地址。这里明确指定"https://api.deepseek.com"。这意味着,虽然你用了OpenAI的库,但你的请求实际上会被发送到DeepSeek的服务器,而不是OpenAI的服务器
更多推荐




所有评论(0)