conn.State和conn.errors.count的选择

作者上班时遇到网站提示数据库链接失败,原判断连接是否成功的代码存在失误。后通过查阅ado的chm手册,找到conn的state属性,利用其值判断连接状态,将判断句修改后,测试所有错误成功状态,拦截工作恢复正常。

早上上班坐下,开机,打开熟悉的工作网站界面,突然发现网站提示数据库链接失败,但是系统作的错误拦截居然没有生效果(数据库链接的原因是数据库服务器没开,这个不是本文重点)。
检查了一下判断连接是否成功的代码发现是这样写的
if conn.errors.count<>0 and conn.errors.count<>2 then
显示链链失败提示
end if
想起,原来是用conn.errors.count<>0来判断是否连接成功,但是老是判断失误,跟踪了一下原因,发现当数据库连接时有时会产生conn.errors.count等于2的结果,但是链接是成功的,所以加上了一个conn.errors.count<>2,但是,这个conn.errors.count=2却包含了所有连接不成功的原因,所以发生了上面说的那一幕。

想了半天没想出个办法,上个洗手间,晕倒,居然在洗手时想到conn有一个检查连接状态的属性(为什么会在去洗手间时想到的呢?),回来查了一下ado的chm手册,找到了state属性,下面是这个属性的一些值
AdStateClosed  默认,指示对象是关闭的。
AdStateOpen   指示对象是打开的。
AdStateConnecting 指示 Recordset 对象正在连接。
AdStateExecuting 指示 Recordset 对象正在执行命令。
AdStateFetching  指示 Recordset 对象的行正在被读取。

查了一下adovbs.ini,这几个状态的真实值是:
Const adStateClosed = &H00000000
Const adStateOpen = &H00000001
Const adStateConnecting = &H00000002
Const adStateExecuting = &H00000004
Const adStateFetching = &H00000008

state还是一个组合值,如当状态是AdStateExecuting Recordset 对象正在执行命令时,真正值应该是AdStateOpen和AdStateExecuting的组合。具体什么样的组合格式,有心人可以试试。我现在的重点是第一个参数adStateClosed,很明显adStateClosed的十进制值是0
那也就是说当conn.State<>0就是链接成功。那判断句就可以改成
if conn.State=0 then
显示链链失败提示
end if
测试所有错误成功状态,拦截工作一切正常。耶~(这个是被MM感染了,喜欢说耶,要吐的吐啊吐的就习惯了的。-_-||b)

# ======================================== # 🚚 在途未入库管理窗口(防重复打开)—— 完整修复版 # ✅ 增加 "已入库" 列,并正确读取 ImportedQty # ======================================== in_transit_open = False def open_in_transit_window(): if not cursor: messagebox.showwarning("警告", "数据库未连接,无法管理在途数据") return global in_transit_open if in_transit_open: messagebox.showwarning("提示", "在途未入库窗口已打开。") return in_transit_open = True window = tk.Toplevel(root) window.title("在途未入库管理") window.geometry("1180x650") # --- 定义变量 --- item_var = tk.StringVar() qty_var = tk.StringVar() so_var_local = tk.StringVar() sn_var_local = tk.StringVar() remark_var = tk.StringVar() ship_date_var = tk.StringVar() search_var = tk.StringVar() # --- 创建 Treeview 表格 --- tree = ttk.Treeview( window, columns=("物料编号", "数量", "销售订单", "序列号", "备注", "发货日期", "已入库"), show="headings", height=22 ) headers = ["物料编号", "数量", "销售订单", "序列号", "备注", "发货日期", "已入库"] widths = [150, 80, 120, 180, 150, 120, 80] for header, width in zip(headers, widths): tree.heading(header, text=header) tree.column(header, width=width, anchor='center') tree.grid(row=8, column=0, columnspan=4, padx=10, pady=10, sticky="nsew") # ======================================== # ✅ 功能函数定义 # ======================================== def refresh_list(filter_text=""): """刷新表格数据,可带搜索过滤""" for row in tree.get_children(): tree.delete(row) try: if filter_text.strip(): like_filter = f"%{filter_text}%" query = """ SELECT Item, Qty, SO, SN, 备注, 发货日期, ImportedQty FROM [in_transit] WHERE Item LIKE ? OR Qty LIKE ? OR SO LIKE ? OR SN LIKE ? OR 备注 LIKE ? OR 发货日期 LIKE ? OR CAST(ImportedQty AS VARCHAR) LIKE ? """ params = (like_filter,) * 7 # 注意:现在是7个参数 cursor.execute(query, params) else: cursor.execute("SELECT Item, Qty, SO, SN, 备注, 发货日期, ImportedQty FROM [in_transit]") for row in cursor.fetchall(): values = [ str(row[0] or ""), # Item str(row[1]), # Qty str(row[2] or ""), # SO str(row[3] or ""), # SN str(row[4] or ""), # 备注 str(row[5] or ""), # 发货日期 str(row[6] or "0") # ImportedQty → 显示为“已入库” ] tree.insert("", tk.END, values=values) except Exception as e: messagebox.showerror("读取失败", f"无法加载在途数据:\n{e}") def add_record(): """添加新记录,默认 ImportedQty=0""" item = item_var.get().strip() qty = qty_var.get().strip() so = so_var_local.get().strip() sn = sn_var_local.get().strip() remark = remark_var.get().strip() ship_date = ship_date_var.get().strip() if not item or not qty: messagebox.showwarning("提示", "请至少输入【物料编号】【数量】") return try: float(qty) except ValueError: messagebox.showwarning("提示", "数量必须是数字") return try: cursor.execute(""" INSERT INTO [in_transit] (Item, Qty, SO, SN, 备注, 发货日期, ImportedQty) VALUES (?, ?, ?, ?, ?, ?, ?) """, (item, qty, so, sn, remark, ship_date, 0)) # 初始化 ImportedQty 为 0 conn.commit() messagebox.showinfo("成功", "✅ 记录已添加") clear_inputs() refresh_list() except Exception as e: conn.rollback() messagebox.showerror("错误", f"添加失败:\n{e}") def delete_record(): """删除选中的记录""" selected = tree.selection() if not selected: messagebox.showwarning("提示", "请先选择要删除的记录") return item = tree.item(selected[0])['values'][0] sn = tree.item(selected[0])['values'][3] if messagebox.askyesno("确认删除", f"确定要删除该在途记录?\n物料编号:{item}\n序列号:{sn}"): try: cursor.execute("DELETE FROM [in_transit] WHERE Item = ? AND SN = ?", (item, sn)) conn.commit() messagebox.showinfo("成功", "🗑️ 记录已删除") refresh_list() except Exception as e: conn.rollback() messagebox.showerror("错误", f"删除失败:\n{e}") def on_double_click(event): """双击编辑记录""" selected = tree.selection() if not selected: return item_values = tree.item(selected[0])['values'] original_item, original_sn = item_values[0], item_values[3] edit_win = tk.Toplevel(window) edit_win.title("编辑在途记录") edit_win.geometry("500x420") v_item = tk.StringVar(value=item_values[0]) v_qty = tk.StringVar(value=item_values[1]) v_so = tk.StringVar(value=item_values[2]) v_sn = tk.StringVar(value=item_values[3]) v_remark = tk.StringVar(value=item_values[4]) v_ship_date = tk.StringVar(value=item_values[5]) fields = [ ("物料编号", v_item), ("数量", v_qty), ("销售订单", v_so), ("序列号", v_sn), ("备注", v_remark), ("发货日期", v_ship_date), ] for i, (label, var) in enumerate(fields): ttk.Label(edit_win, text=label).grid(row=i, column=0, padx=15, pady=6, sticky='e') ttk.Entry(edit_win, textvariable=var, width=30).grid(row=i, column=1, padx=15, pady=6, sticky='w') def save_edit(): new_item = v_item.get().strip() new_qty = v_qty.get().strip() new_so = v_so.get().strip() new_sn = v_sn.get().strip() new_remark = v_remark.get().strip() new_ship_date = v_ship_date.get().strip() if not new_item or not new_qty: messagebox.showwarning("提示", "物料编号数量不能为空") return try: float(new_qty) except ValueError: messagebox.showwarning("提示", "数量必须是有效数字") return try: cursor.execute(""" UPDATE [in_transit] SET Item = ?, Qty = ?, SO = ?, SN = ?, 备注 = ?, 发货日期 = ? WHERE Item = ? AND SN = ? """, (new_item, new_qty, new_so, new_sn, new_remark, new_ship_date, original_item, original_sn)) conn.commit() messagebox.showinfo("成功", "💾 修改已保存") edit_win.destroy() refresh_list() window.lift() except Exception as e: conn.rollback() messagebox.showerror("错误", f"更新失败:\n{e}") ttk.Button(edit_win, text="保存修改", command=save_edit).grid(row=len(fields), column=0, columnspan=2, pady=20) def clear_inputs(): """清空输入框""" item_var.set("") qty_var.set("") so_var_local.set("") sn_var_local.set("") remark_var.set("") ship_date_var.set("") def copy_selected(): """复制选中行内容到剪贴板""" selected = tree.selection() if selected: values = tree.item(selected[0])['values'] text = '\t'.join(str(v) for v in values) window.clipboard_clear() window.clipboard_append(text) def show_context_menu(event): """右键弹出菜单""" if tree.identify_row(event.y): tree.selection_set(tree.identify_row(event.y)) context_menu.post(event.x_root, event.y_root) def import_from_excel(): """从 Excel 导入并覆盖所有在途数据""" filepath = filedialog.askopenfilename( title="选择在途数据Excel文件", filetypes=[("Excel 文件", "*.xlsx"), ("所有文件", "*.*")] ) if not filepath: return if not messagebox.askyesno("⚠️ 确认操作", "此操作将清空当前所有在途数据,\n并用Excel中的数据完全替换。\n\n是否继续?"): return try: df = pd.read_excel(filepath) required_columns = {'Item', 'Qty', 'SO', 'SN', '备注', '发货日期'} missing = required_columns - set(df.columns) if missing: messagebox.showerror("格式错误", f"❌ 缺少必要列:{missing}\n请确保包含以下列:\n{required_columns}") return df['Item'] = df['Item'].astype(str).str.strip() df['Qty'] = pd.to_numeric(df['Qty'], errors='coerce').fillna(0) df['SO'] = df['SO'].astype(str).str.strip() df['SN'] = df['SN'].astype(str).str.strip() df['备注'] = df['备注'].astype(str).str.strip() df['发货日期'] = df['发货日期'].astype(str).str.strip() valid_df = df.dropna(subset=['Item']).query('Item != "nan" and Item != ""') if valid_df.empty: messagebox.showwarning("无有效数据", "Excel 中没有可导入的有效数据行。") return cursor.execute("DELETE FROM [in_transit]") inserted_count = 0 for _, row in valid_df.iterrows(): cursor.execute(""" INSERT INTO [in_transit] (Item, Qty, SO, SN, 备注, 发货日期, ImportedQty) VALUES (?, ?, ?, ?, ?, ?, ?) """, (row['Item'], row['Qty'], row['SO'], row['SN'], row['备注'], row['发货日期'], 0)) inserted_count += 1 conn.commit() messagebox.showinfo("导入成功", f"✅ 已成功导入 {inserted_count} 条在途记录!") refresh_list() except Exception as e: conn.rollback() messagebox.showerror("导入失败", f"发生错误:\n{str(e)}") 在以上代码中修改 并提供完整代码
09-26
def open_in_transit_window(): if not cursor: messagebox.showwarning("警告", "数据库未连接,无法管理在途数据") return global in_transit_open if in_transit_open: messagebox.showwarning("提示", "在途未入库窗口已打开。") return in_transit_open = True window = tk.Toplevel(root) window.title("在途未入库管理") window.geometry("1180x650") window.resizable(True, True) item_var = tk.StringVar() qty_var = tk.StringVar() so_var_local = tk.StringVar() sn_var_local = tk.StringVar() remark_var = tk.StringVar() search_var = tk.StringVar() tree = ttk.Treeview( window, columns=("物料编号", "数量", "销售订单", "序列号", "备注", "发货日期", "已入库"), show="headings", height=22 ) headers = ["物料编号", "数量", "销售订单", "序列号", "备注", "发货日期", "已入库"] widths = [150, 80, 120, 180, 150, 120, 80] for header, width in zip(headers, widths): tree.heading(header, text=header) tree.column(header, width=width, anchor='center') tree.grid(row=8, column=0, columnspan=4, padx=10, pady=10, sticky="nsew") v_scroll = ttk.Scrollbar(window, orient="vertical", command=tree.yview) h_scroll = ttk.Scrollbar(window, orient="horizontal", command=tree.xview) tree.configure(yscrollcommand=v_scroll.set, xscrollcommand=h_scroll.set) v_scroll.grid(row=8, column=4, sticky='ns') h_scroll.grid(row=9, column=0, columnspan=4, sticky='ew') def refresh_list(filter_text=""): for row in tree.get_children(): tree.delete(row) try: if filter_text.strip(): query = """SELECT Item, Qty, SO, SN, 备注, 发货日期, ImportedQty FROM in_transit WHERE Item LIKE %s""" cursor.execute(query, (f"%{filter_text}%",)) else: cursor.execute("SELECT Item, Qty, SO, SN, 备注, 发货日期, ImportedQty FROM in_transit") for row in cursor.fetchall(): values = [str(row[i] or "") for i in range(6)] values.append(str(row[6] or "0")) tree.insert("", tk.END, values=values) except Exception as e: messagebox.showerror("读取失败", f"无法加载在途数据:\n{e}") def add_record(): item = item_var.get().strip() qty_str = qty_var.get().strip() so = so_var_local.get().strip() sn = sn_var_local.get().strip() remark = remark_var.get().strip() if not item or not qty_str: return try: qty = float(qty_str) if qty <= 0: raise ValueError except ValueError: messagebox.showwarning("提示", "数量必须是大于0的有效数字") return ship_date = datetime.now().strftime("%Y-%m-%d %H:%M") try: cursor.execute("INSERT INTO in_transit (Item, Qty, SO, SN, 备注, 发货日期, ImportedQty) VALUES (%s,%s,%s,%s,%s,%s,%s)", (item, qty, so, sn, remark, ship_date, 0)) conn.commit() messagebox.showinfo("成功", "✅ 记录已添加") clear_inputs() refresh_list() except Exception as e: conn.rollback() messagebox.showerror("错误", f"添加失败:\n{e}") def delete_record(): selected = tree.selection() if not selected: return item = tree.item(selected[0])['values'][0] sn = tree.item(selected[0])['values'][3] if messagebox.askyesno("确认删除", f"确定要删除该在途记录?\n物料编号:{item}\n序列号:{sn}"): try: cursor.execute("DELETE FROM in_transit WHERE Item = %s AND SN = %s", (item, sn)) conn.commit() messagebox.showinfo("成功", "🗑️ 记录已删除") refresh_list() except Exception as e: conn.rollback() messagebox.showerror("错误", f"删除失败:\n{e}") def on_double_click(event): selected = tree.selection() if not selected: return values = tree.item(selected[0])['values'] original_item, original_sn = values[0], values[3] edit_win = tk.Toplevel(window) edit_win.title("编辑在途记录") edit_win.geometry("500x420") edit_win.resizable(False, False) vars = [tk.StringVar(value=v) for v in values[:-1]] fields = ["物料编号", "数量", "销售订单", "序列号", "备注", "发货日期(只读)"] for i, (label, var) in enumerate(zip(fields, vars)): ttk.Label(edit_win, text=label).grid(row=i, column=0, padx=15, pady=6, sticky='e') if "只读" not in label: ttk.Entry(edit_win, textvariable=var, width=30).grid(row=i, column=1, padx=15, pady=6, sticky='w') else: readonly_entry = ttk.Entry(edit_win, textvariable=var, state='readonly', width=30) readonly_entry.grid(row=i, column=1, padx=15, pady=6, sticky='w') def save_edit(): new_item = vars[0].get().strip() new_qty = vars[1].get().strip() new_so = vars[2].get().strip() new_sn = vars[3].get().strip() new_remark = vars[4].get().strip() if not new_item or not new_qty: return try: float(new_qty) except ValueError: return try: cursor.execute("UPDATE in_transit SET Item=%s,Qty=%s,SO=%s,SN=%s,备注=%s WHERE Item=%s AND SN=%s", (new_item, new_qty, new_so, new_sn, new_remark, original_item, original_sn)) conn.commit() messagebox.showinfo("成功", "💾 修改已保存") edit_win.destroy() refresh_list() window.lift() except Exception as e: conn.rollback() messagebox.showerror("错误", f"更新失败:\n{e}") ttk.Button(edit_win, text="保存修改", command=save_edit).grid(row=len(fields), column=0, columnspan=2, pady=20) def clear_inputs(): item_var.set(""); qty_var.set(""); so_var_local.set(""); sn_var_local.set(""); remark_var.set("") def copy_selected(): selected = tree.selection() if selected: values = tree.item(selected[0])['values'] text = '\t'.join(str(v) for v in values) window.clipboard_clear() window.clipboard_append(text) def show_context_menu(event): if tree.identify_row(event.y): tree.selection_set(tree.identify_row(event.y)) context_menu.post(event.x_root, event.y_root) def import_from_excel(): filepath = filedialog.askopenfilename(filetypes=[("Excel 文件", "*.xlsx"), ("所有文件", "*.*")]) if not filepath: return if not messagebox.askyesno("⚠️ 确认操作", "清空当前所有在途数据,并用Excel中的数据完全替换?"): return try: df = pd.read_excel(filepath) required_columns = {'Item', 'Qty', 'SO', 'SN', '备注', '发货日期'} if missing := required_columns - set(df.columns): messagebox.showerror("格式错误", f"缺少必要列:{missing}") return # 数据清洗 df['Item'] = df['Item'].astype(str).str.strip() df['Qty'] = pd.to_numeric(df['Qty'], errors='coerce').fillna(0) df['SO'] = df['SO'].astype(str).str.strip() df['SN'] = df['SN'].astype(str).str.strip() df['备注'] = df['备注'].astype(str).str.strip() df['发货日期'] = df['发货日期'].astype(str).str.strip() df.dropna(subset=['Item'], inplace=True) cursor.execute("DELETE FROM in_transit") inserted_count = 0 for _, row in df.iterrows(): cursor.execute("INSERT INTO in_transit (Item, Qty, SO, SN, 备注, 发货日期, ImportedQty) VALUES (%s,%s,%s,%s,%s,%s,%s)", (row['Item'], row['Qty'], row['SO'], row['SN'], row['备注'], row['发货日期'], 0)) inserted_count += 1 conn.commit() messagebox.showinfo("导入成功", f"✅ 已成功导入 {inserted_count} 条记录!") refresh_list() except Exception as e: conn.rollback() messagebox.showerror("导入失败", f"发生错误:\n{str(e)}") def import_from_excel_append(): """从 Excel 追加导入在途数据(允许重复,不跳过任何行)""" filepath = filedialog.askopenfilename( title="选择在途数据Excel文件(追加导入,允许重复)", filetypes=[("Excel 文件", "*.xlsx"), ("所有文件", "*.*")] ) if not filepath: return try: df = pd.read_excel(filepath) required_columns = {'Item', 'Qty', 'SO', 'SN', '备注', '发货日期'} missing = required_columns - set(df.columns) if missing: messagebox.showerror("格式错误", f"❌ 缺少必要列:{missing}\n请确保包含以下列:\n{required_columns}") return # 数据清洗 df['Item'] = df['Item'].astype(str).str.strip() df['Qty'] = pd.to_numeric(df['Qty'], errors='coerce').fillna(0) df['SO'] = df['SO'].astype(str).str.strip() df['SN'] = df['SN'].astype(str).str.strip() df['备注'] = df['备注'].astype(str).str.strip() df['发货日期'] = df['发货日期'].astype(str).str.strip() # 过滤有效行:仅保留非空物料编号 valid_df = df.dropna(subset=['Item']).query('Item != "nan" and Item != ""') if valid_df.empty: messagebox.showwarning("无有效数据", "Excel 中没有可导入的有效数据行。") return # 开始插入(无条件追加) inserted_count = 0 for _, row in valid_df.iterrows(): try: cursor.execute(""" INSERT INTO in_transit (Item, Qty, SO, SN, 备注, 发货日期, ImportedQty) VALUES (%s, %s, %s, %s, %s, %s, %s) """, (row['Item'], row['Qty'], row['SO'], row['SN'], row['备注'], row['发货日期'], 0)) inserted_count += 1 except Exception as e: print(f"插入失败(忽略): {e}") # 日志输出,不影响整体导入 conn.commit() messagebox.showinfo("追加导入完成", f"✅ 已无条件追加 {inserted_count} 条记录(含可能的重复)") refresh_list() except Exception as e: conn.rollback() messagebox.showerror("导入失败", f"发生错误:\n{str(e)}") inputs = [("物料编号", item_var), ("数量", qty_var), ("销售订单", so_var_local), ("序列号", sn_var_local), ("备注", remark_var)] for i, (label, var) in enumerate(inputs): ttk.Label(window, text=label).grid(row=i, column=0, padx=10, pady=4, sticky='e') ttk.Entry(window, textvariable=var, width=25).grid(row=i, column=1, padx=10, pady=4, sticky='w') ttk.Label(window, text="发货日期:").grid(row=5, column=0, padx=10, pady=4, sticky='e') date_label = tk.Label(window, text=datetime.now().strftime("%Y-%m-%d %H:%M"), fg="blue", font=("Arial", 12, "bold")) date_label.grid(row=5, column=1, padx=10, pady=4, sticky='w') ttk.Label(window, text="* 新增记录将使用当前日期作为发货日期", foreground="gray", font=("Arial", 10)) \ .grid(row=6, column=0, columnspan=2, padx=10, pady=2, sticky='w') # 创建按钮框架,并左对齐 button_frame = ttk.Frame(window) button_frame.grid(row=7, column=0, columnspan=4, pady=10, sticky='w', padx=(10, 0)) # 在 frame 内部使用 pack 左对齐,并 anchor='w' 确保紧贴左边 ttk.Button(button_frame, text="➕ 添加记录", command=add_record).pack(side="left", padx=5) ttk.Button(button_frame, text="🗑️ 删除选中", command=delete_record).pack(side="left", padx=5) ttk.Button(button_frame, text="🔄 从Excel导入并覆盖", command=import_from_excel).pack(side="left", padx=5) ttk.Button(button_frame, text="📥 追加导入(允许重复)", command=import_from_excel_append).pack(side="left", padx=5) # 可选:防止 frame 自动扩展居中 button_frame.columnconfigure(0, weight=0) # 禁止拉伸 ttk.Label(window, text="🔍 搜索").grid(row=7, column=2, padx=10, pady=9, sticky='e') ttk.Entry(window, textvariable=search_var, width=30).grid(row=7, column=3, padx=10, pady=9, sticky='w') search_var.trace_add("write", lambda *args: refresh_list(search_var.get())) context_menu = tk.Menu(window, tearoff=0); context_menu.add_command(label="📋 复制整行", command=copy_selected) tree.bind("<Button-3>", show_context_menu); tree.bind("<Double-1>", on_double_click) refresh_list() def on_close(): global in_transit_open; in_transit_open = False; window.destroy() window.protocol("WM_DELETE_WINDOW", on_close) window.grid_rowconfigure(8, weight=1); window.grid_columnconfigure(1, weight=1) window.transient(root); window.grab_set() 修改隐藏按钮输入框 提供完整修改代码
最新发布
09-30
下次请把要修改的文件的位置,名称告诉我 然后我把文件发给你,你改好了(要完整的),再还给我,这是E:\AI_System\agent里的environment_interface.py:“import os import psutil import platform import json import sqlite3 import sys import subprocess import requests import logging from datetime import datetime from pathlib import Path logger = logging.getLogger('EnvironmentInterface') class EnvironmentInterface: def __init__(self, base_dir: str): # 配置日志 self.logger = logging.getLogger('EnvironmentInterface') self.logger.setLevel(logging.INFO) console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')) self.logger.addHandler(console_handler) self.logger.propagate = False # 工作区路径设置(使用绝对路径) self.workspace_root = self._resolve_workspace_path(base_dir) # 解析路径并确保目录存在 self.models_dir = self._resolve_and_create_dir(os.path.join(self.workspace_root, "01_模型存储")) self.cache_dir = self._resolve_and_create_dir(os.path.join(self.workspace_root, "01_模型存储", "下载缓存")) self.system_dir = self._resolve_and_create_dir(os.path.join(self.workspace_root, "02_核心代码")) self.temp_dir = self._resolve_and_create_dir(os.path.join(self.workspace_root, "04_环境工具", "临时补丁")) self.python_dir = self._resolve_and_create_dir(os.path.join(self.workspace_root, "04_环境工具", "Python环境")) # 环境配置 os.environ['PATH'] = f"{self.python_dir};{self.python_dir}\\Scripts;{os.environ['PATH']}" os.environ['HF_HOME'] = self.cache_dir # 安全策略 self.authorized_actions = { "file_access": True, "web_search": True, "command_exec": True, "software_install": False, "hardware_control": False } self.action_log = [] # 初始化数据库(使用绝对路径) self.environment_db = os.path.join(self.system_dir, 'environment.db') self._init_db() self.logger.info("✅ 环境接口初始化完成") def _resolve_workspace_path(self, base_dir: str) -> str: """解析工作区路径为绝对路径""" try: # 使用Path对象确保跨平台兼容性 base_path = Path(base_dir).resolve() workspace_path = base_path / "AI_Workspace" if not workspace_path.exists(): workspace_path.mkdir(parents=True, exist_ok=True) self.logger.info(f"创建工作区目录: {workspace_path}") return str(workspace_path) except Exception as e: self.logger.error(f"工作区路径解析失败: {str(e)}") # 回退到默认路径 fallback_path = os.path.join(os.path.expanduser("~"), "AI_Workspace") os.makedirs(fallback_path, exist_ok=True) return fallback_path def _resolve_and_create_dir(self, path): """解析路径并确保目录存在""" try: # 转换为绝对路径 abs_path = os.path.abspath(path) # 创建目录(如果不存在) if not os.path.exists(abs_path): os.makedirs(abs_path, exist_ok=True) self.logger.info(f"创建目录: {abs_path}") return abs_path except Exception as e: self.logger.error(f"目录解析失败: {path} - {str(e)}") # 创建临时目录作为回退 temp_path = os.path.join(self.workspace_root, "temp") os.makedirs(temp_path, exist_ok=True) return temp_path def _init_db(self): """初始化环境数据库""" try: conn = sqlite3.connect(self.environment_db) c = conn.cursor() # 系统信息表 c.execute('''CREATE TABLE IF NOT EXISTS system_info ( id INTEGER PRIMARY KEY, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, os TEXT, cpu TEXT, memory REAL, disk_usage REAL )''') # 文件探索历史表 c.execute('''CREATE TABLE IF NOT EXISTS file_exploration ( id INTEGER PRIMARY KEY, path TEXT UNIQUE, last_visited DATETIME, visit_count INTEGER DEFAULT 0 )''') # 资源管理表 c.execute('''CREATE TABLE IF NOT EXISTS resources ( id INTEGER PRIMARY KEY, name TEXT, type TEXT CHECK(type IN ('skin', 'furniture', 'tool')), path TEXT, is_active BOOLEAN DEFAULT 0 )''') conn.commit() conn.close() self.logger.info(f"✅ 数据库初始化完成: {self.environment_db}") except Exception as e: self.logger.error(f"❌ 数据库初始化失败: {str(e)}") # 系统监控功能 def get_system_info(self): """获取并记录系统信息""" try: # 获取内存使用情况 mem = psutil.virtual_memory() mem_used = round(mem.used / (1024 ** 3), 1) mem_total = round(mem.total / (1024 ** 3), 1) # 获取磁盘使用情况 disk_usage = psutil.disk_usage('/').percent info = { "os": f"{platform.system()} {platform.release()}", "cpu": f"{platform.processor()} ({psutil.cpu_count(logical=False)} cores)", "memory": f"{mem_used}GB/{mem_total}GB", "disk_usage": f"{disk_usage}%" } # 保存到数据库 conn = sqlite3.connect(self.environment_db) c = conn.cursor() c.execute('''INSERT INTO system_info (os, cpu, memory, disk_usage) VALUES (?, ?, ?, ?)''', (info['os'], info['cpu'], mem_used, disk_usage)) conn.commit() conn.close() self.log_action("system_monitor", "采集系统信息") return info except Exception as e: self.logger.error(f"❌ 获取系统信息失败: {str(e)}") return { "os": f"Error: {str(e)}", "cpu": "0%", "memory": "0GB/0GB", "disk_usage": "0%" } # 文件探索功能 def explore_directory(self, path=None): """探索目录内容""" try: target_path = path or self.workspace_root target_path = os.path.abspath(target_path) # 安全路径检查 if not target_path.startswith(os.path.abspath(self.workspace_root)): return {"error": "访问路径超出工作区范围"} if not os.path.exists(target_path): return {"error": "路径不存在"} # 记录探索历史 self._record_exploration(target_path) contents = [] for item in os.listdir(target_path): full_path = os.path.join(target_path, item) try: is_dir = os.path.isdir(full_path) size = os.path.getsize(full_path) if not is_dir else 0 modified_time = os.path.getmtime(full_path) contents.append({ "name": item, "type": "directory" if is_dir else "file", "path": full_path, "size": f"{size / 1024:.1f}KB" if size < 1024 ** 2 else f"{size / (1024 ** 2):.1f}MB", "modified": datetime.fromtimestamp(modified_time).strftime("%Y-%m-%d %H:%M") }) except PermissionError: contents.append({ "name": item, "type": "unknown", "error": "权限不足" }) except Exception as e: contents.append({ "name": item, "type": "unknown", "error": str(e) }) self.log_action("file_explore", f"探索路径: {target_path}") return { "current_path": target_path, "contents": sorted(contents, key=lambda x: (x['type'] == 'directory', x['name']), reverse=True) } except Exception as e: self.logger.error(f"❌ 探索目录失败: {str(e)}") return {"error": str(e)} def _record_exploration(self, path): """记录探索历史到数据库""" try: conn = sqlite3.connect(self.environment_db) c = conn.cursor() c.execute("SELECT id FROM file_exploration WHERE path = ?", (path,)) if c.fetchone(): c.execute('''UPDATE file_exploration SET last_visited = CURRENT_TIMESTAMP, visit_count = visit_count + 1 WHERE path = ?''', (path,)) else: c.execute('''INSERT INTO file_exploration (path, last_visited, visit_count) VALUES (?, CURRENT_TIMESTAMP, 1)''', (path,)) conn.commit() except Exception as e: self.logger.error(f"❌ 记录探索历史失败: {str(e)}") finally: conn.close() # 资源管理功能 def get_resource(self, resource_type): """获取特定类型资源""" try: conn = sqlite3.connect(self.environment_db) c = conn.cursor() c.execute('''SELECT name, path, is_active FROM resources WHERE type = ?''', (resource_type,)) resources = [ {"name": item[0], "path": item[1], "is_active": bool(item[2])} for item in c.fetchall() ] return resources except Exception as e: self.logger.error(f"❌ 获取资源失败: {str(e)}") return [] finally: conn.close() def activate_resource(self, resource_name): """激活特定资源""" try: conn = sqlite3.connect(self.environment_db) c = conn.cursor() c.execute('''UPDATE resources SET is_active = 0 WHERE type = (SELECT type FROM resources WHERE name = ?)''', (resource_name,)) c.execute('''UPDATE resources SET is_active = 1 WHERE name = ?''', (resource_name,)) conn.commit() self.log_action("resource_activate", f"激活资源: {resource_name}") return True except Exception as e: self.logger.error(f"❌ 激活资源失败: {str(e)}") return False finally: conn.close() # 工作区管理功能 def get_workspace_info(self): """获取工作区信息""" return { "workspace": self.workspace_root, "models": self.models_dir, "system": self.system_dir, "cache": self.cache_dir, "temp": self.temp_dir, "python": self.python_dir } # 辅助功能 def _is_authorized(self, action): """检查操作授权状态""" return self.authorized_actions.get(action, False) def log_action(self, action, details): """记录环境操作日志""" log_entry = { "timestamp": datetime.now().isoformat(), "action": action, "details": details } self.action_log.append(log_entry) # 保存到文件 log_file = os.path.join(self.workspace_root, "environment_actions.log") try: with open(log_file, 'a', encoding='utf-8') as f: f.write(json.dumps(log_entry, ensure_ascii=False) + "\n") except Exception as e: self.logger.error(f"❌ 记录日志失败: {str(e)}") # 同时记录到logger self.logger.info(f"{action}: {details}") return True # 使用示例 if __name__ == "__main__": # 配置日志 logging.basicConfig(level=logging.INFO) # 创建环境接口实例 env = EnvironmentInterface(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # 获取工作区信息 print("工作区信息:", json.dumps(env.get_workspace_info(), indent=2, ensure_ascii=False)) # 获取系统信息 print("系统信息:", json.dumps(env.get_system_info(), indent=2, ensure_ascii=False)) # 探索目录 print("工作区内容:", json.dumps(env.explore_directory(), indent=2, ensure_ascii=False)) ”E:\AI_System\agent里的autonomous_agent.py:“import os import time import logging from dotenv import load_dotenv # 使用绝对导入 from core.config import system_config from core.environment import DefaultEnvironment, AIHome, ActionExecutor from .environment_interface import EnvironmentInterface # 导入修复后的环境接口 class AutonomousAgent: def __init__(self): self.logger = self._setup_logger() self.logger.info("🔁 初始化自主智能体核心模块...") try: # 加载环境变量 load_dotenv() # 初始化环境感知系统 self._initialize_environment_systems() # 初始化各子系统 self._initialize_subsystems() self.logger.info("✅ 自主智能体初始化完成") except Exception as e: self.logger.error(f"❌ 智能体初始化失败: {str(e)}") raise def _setup_logger(self): """配置日志记录器""" logger = logging.getLogger('AutonomousAgent') logger.setLevel(system_config.LOG_LEVEL) # 创建控制台处理器 console_handler = logging.StreamHandler() console_handler.setLevel(system_config.LOG_LEVEL) # 创建格式化器 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') console_handler.setFormatter(formatter) # 添加处理器 logger.addHandler(console_handler) logger.propagate = False return logger def _initialize_environment_systems(self): """初始化环境感知系统 - 修复后""" # 获取项目根目录 base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 修复:使用具体实现类 DefaultEnvironment self.environment = DefaultEnvironment(base_dir) self.logger.info("✅ 环境接口初始化完成") # 初始化智能家居环境 self.home = AIHome(base_dir) self.logger.info("✅ 智能家居环境初始化完成") # 修复:ActionExecutor 不需要参数 self.executor = ActionExecutor() self.logger.info("✅ 动作执行器初始化完成") # 新增:初始化环境接口(用于数据库资源管理) self.env_interface = EnvironmentInterface(base_dir) self.logger.info("✅ 环境接口(数据库)初始化完成") # 记录环境状态 env_status = self.environment.get_system_info() self.logger.info(f"📊 系统状态: OS={env_status['os']}, CPU={env_status['cpu']}, " f"内存={env_status['memory']}GB, 磁盘={env_status['disk_usage']}%") def _initialize_subsystems(self): """初始化所有子系统""" # 1. 初始化模型管理器 from .model_manager import ModelManager self.model_manager = ModelManager( model_dir=system_config.MODEL_DIR, device=system_config.DEVICE, default_model=system_config.DEFAULT_MODEL ) self.logger.info("✅ 模型管理器初始化完成") # 2. 初始化健康系统 from .health_system import HealthSystem self.health_system = HealthSystem(self) self.logger.info("✅ 健康系统初始化完成") # 3. 初始化记忆系统 from .memory_system import MemorySystem self.memory_system = MemorySystem(self) self.logger.info("✅ 记忆系统初始化完成") # 4. 初始化情感系统 from .affective_system import AffectiveSystem self.affective_system = AffectiveSystem(agent=self) self.logger.info("✅ 情感系统初始化完成") # 5. 初始化认知架构 from .cognitive_architecture import CognitiveArchitecture self.cognitive_architecture = CognitiveArchitecture(agent=self) self.logger.info("✅ 认知架构初始化完成") # 6. 初始化通信系统 from .communication_system import CommunicationSystem self.communication_system = CommunicationSystem( cognitive_system=self.cognitive_architecture, agent=self # 传递智能体实例 ) self.logger.info("✅ 通信系统初始化完成") def process_input(self, user_input, user_id="default"): """处理用户输入(通过通信系统)""" return self.communication_system.process_input(user_input, user_id) def run_periodic_tasks(self): """运行周期性任务""" # 更新健康状态 self.health_system.update() # 情感系统更新 self.affective_system.grow() # 记忆系统维护 self.memory_system.consolidate_memories() # 修复:环境状态监控 - 使用时间戳 current_time = time.time() if not hasattr(self, "_last_env_check"): self._last_env_check = current_time # 每5分钟检查一次 if current_time - self._last_env_check > 300: self._last_env_check = current_time self._monitor_environment() def _monitor_environment(self): """监控环境状态 - 修复后""" try: # 获取当前系统状态 env_status = self.environment.get_system_info() # 安全解析磁盘使用率 disk_str = env_status.get('disk_usage', '0%').strip() if disk_str.endswith('%'): try: disk_usage = float(disk_str[:-1]) except ValueError: disk_usage = 0.0 else: disk_usage = 0.0 if disk_usage > 90: self.logger.warning(f"⚠️ 磁盘空间不足!当前使用率: {disk_usage}%") # 安全解析内存使用 memory_str = env_status.get('memory', '0GB/0GB') try: # 支持多种格式: "3.2GB/16GB" 或 "3.2/16.0 GB" parts = memory_str.replace('GB', '').replace(' ', '').split('/') if len(parts) >= 2: memory_used = float(parts[0]) memory_total = float(parts[1]) memory_ratio = memory_used / memory_total if memory_ratio > 0.85: self.logger.warning( f"⚠️ 内存使用过高!已用: {memory_used:.1f}GB, " f"总共: {memory_total:.1f}GB, " f"使用率: {memory_ratio * 100:.1f}%" ) except (ValueError, TypeError, ZeroDivisionError) as e: self.logger.error(f"内存数据解析失败: {memory_str} - {str(e)}") # 记录到健康系统 self.health_system.record_environment_status(env_status) except Exception as e: self.logger.error(f"环境监控失败: {str(e)}", exc_info=True) def get_status(self): """获取智能体状态报告""" # 获取基础状态 status = { "health": self.health_system.get_status(), "affective": self.affective_system.get_state(), "memory_stats": self.memory_system.get_stats(), "model": self.model_manager.get_current_model_info() } # 添加环境信息 try: env_status = self.environment.get_system_info() status["environment"] = { "os": env_status.get("os", "未知"), "cpu": env_status.get("cpu", "0%"), "memory": env_status.get("memory", "0GB/0GB"), "disk": env_status.get("disk_usage", "0%") } except Exception as e: status["environment"] = {"error": str(e)} return status # 环境交互方法 def explore_environment(self, path=None): """探索环境目录""" try: return self.environment.explore_directory(path) except Exception as e: self.logger.error(f"环境探索失败: {str(e)}") return {"error": str(e)} def execute_action(self, action, parameters): """通过执行器执行动作""" try: result = self.executor.execute(action, parameters) self.logger.info(f"执行动作: {action} {parameters} → {result.get('status', '未知')}") return result except Exception as e: self.logger.error(f"动作执行失败: {action} {parameters} - {str(e)}") return {"status": "error", "message": str(e)} ”没找到你说的agent_controller.py,只看见agent_core.py:“from agent.cognitive_architecture import CognitiveArchitecture from .model_manager import ModelManager from .memory_system import MemorySystem from .knowledge_manager import KnowledgeManager from .decision_system import DecisionSystem from .affective_system import AffectiveSystem from .health_system import HealthSystem from .environment_interface import EnvironmentInterface from .communication_system import CommunicationSystem class AgentCore: def __init__(self, config): self.config = config self.model_manager = ModelManager(config) self.memory = MemorySystem(config) self.knowledge = KnowledgeManager(config, self.memory) self.cognition = CognitiveArchitecture(config, self.model_manager) self.affect = AffectiveSystem(config) self.decision = DecisionSystem(config, self.cognition, self.affect) self.environment = EnvironmentInterface(config) self.communication = CommunicationSystem(config) self.health = HealthSystem(config) self.initialized = False def initialize(self): """初始化所有核心组件""" if self.initialized: return True try: # 加载默认模型 self.model_manager.load_model(self.config.DEFAULT_MODEL) # 初始化认知架构 self.cognition.initialize() # 加载环境接口 self.environment.load_environment() # 启动健康监测 self.health.start_monitoring() self.initialized = True return True except Exception as e: print(f"❌ 智能体初始化失败: {str(e)}") return False def process_input(self, input_data): """处理输入数据""" if not self.initialized: return {"error": "Agent not initialized"} # 认知处理 processed = self.cognition.process_input(input_data) # 情感评估 affective_response = self.affect.evaluate(processed) # 决策生成 decision = self.decision.make_decision(processed, affective_response) # 执行行动 result = self.environment.execute_action(decision) # 更新记忆 self.memory.store_experience({ "input": input_data, "processed": processed, "decision": decision, "result": result }) return result”
08-10
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值