VK机器人报错‘name 'event' is not defined’修复及定时余额追加实现
问题解决与代码实现
错误原因
name 'event' is not defined 是因为 event 是VK机器人事件回调函数中的局部变量,独立线程函数 loop2 无法直接访问该变量。你想在线程里操作的用户ID(event.obj.peer_id)只能从事件回调中获取,不能直接在线程里引用。
实现方案
要实现每分钟给用户余额加随机数且不干扰交互,需要:
- 维护所有需要更新余额的用户ID列表
- 线程定时遍历用户列表,逐个更新对应余额文件
- 用文件锁避免多线程读写冲突
- 调整定时为每分钟一次
修改后的完整代码
import threading import time import random import os from filelock import FileLock # 存储用户ID的文件路径 USERS_FILE = "active_users.txt" # 余额文件的存储目录 BALANCE_DIR = "balances" # 初始化目录和文件 os.makedirs(BALANCE_DIR, exist_ok=True) if not os.path.exists(USERS_FILE): with open(USERS_FILE, "w") as f: pass def get_active_users(): """读取活跃用户ID列表""" with open(USERS_FILE, "r") as f: return [line.strip() for line in f if line.strip().isdigit()] def add_active_user(user_id): """添加用户到活跃列表(避免重复)""" user_id_str = str(user_id) users = get_active_users() if user_id_str not in users: with open(USERS_FILE, "a") as f: f.write(f"{user_id_str}\n") def update_user_balance(user_id): """更新单个用户的余额""" user_id_str = str(user_id) balance_file = os.path.join(BALANCE_DIR, f"{user_id_str}.txt") lock_file = f"{balance_file}.lock" # 使用文件锁避免多线程读写冲突 with FileLock(lock_file): # 读取现有余额,不存在则初始化为0 if os.path.exists(balance_file): with open(balance_file, "r") as f: balance = int(f.read().strip() or 0) else: balance = 0 # 增加随机金额 add_amount = random.randint(10000, 100000) balance += add_amount # 写入新余额 with open(balance_file, "w") as f: f.write(str(balance)) print(f"用户 {user_id_str} 余额增加 {add_amount},当前余额: {balance}") def balance_update_loop(): """定时更新所有用户余额的线程函数""" while True: try: users = get_active_users() if users: for user_id in users: update_user_balance(user_id) print("本轮余额更新完成") # 每分钟执行一次 time.sleep(60) except Exception as e: print(f"余额更新线程出错: {e}") # 示例VK机器人事件处理函数(根据你用的VK库调整,比如vk_api) def handle_vk_event(event): """处理用户消息事件,初始化用户余额并添加到活跃列表""" user_id = event.obj.peer_id add_active_user(user_id) # 这里处理用户的对话逻辑,比如回复消息 # api.messages.send(peer_id=user_id, message="你好!", random_id=random.randint(0, 1000000)) # 启动余额更新线程 threading.Thread(target=balance_update_loop, daemon=True).start() # 这里启动VK机器人的事件监听(根据你用的库调整) # 比如vk_api的longpoll监听: # longpoll = VkLongPoll(api) # for event in longpoll.listen(): # if event.type == VkEventType.MESSAGE_NEW and event.to_me: # handle_vk_event(event)
关键说明
- 用户管理:用户第一次发消息时,
handle_vk_event会把用户ID添加到活跃列表,确保线程能找到要更新的用户 - 文件锁:用
FileLock解决多线程同时读写余额文件的冲突问题 - 定时逻辑:线程每60秒执行一次余额更新,不影响主线程的对话交互
- 容错处理:处理余额文件不存在的情况,默认初始余额为0
内容的提问来源于stack exchange,提问作者moki2000m2m
相关产品推荐
相关产品推荐

