Discord机器人分配身份组时触发UnboundLocalError报错求助
问题定位
- cont变量未初始化:仅在校验不通过时给cont赋值为False,所有校验都通过的场景下cont未定义,触发
UnboundLocalError - 角色ID类型错误:discord的角色ID为整数类型,代码中传了字符串格式的ID,会导致无法找到对应身份组
- 长度校验后未终止逻辑:消息分割后长度不等于4时,仅给cont赋值False,后续依然会访问splits的对应下标,触发索引越界错误
- 首段数字校验逻辑错误:判断条件使用了
and逻辑,不可能存在数字同时满足≤0和≥1000,应为or - 首段校验赋值逻辑反向:数字不在1-999范围内时,本应将cont设为False,代码中错误设为True
- 额外问题:未过滤机器人自身发送的消息,可能触发逻辑循环;未调用
process_commands会导致前缀命令失效
修复后完整代码
import os import discord import discord.ext.commands as commands import dotenv import random dotenv.load_dotenv() bot = commands.Bot(command_prefix='$') @bot.event async def on_ready(): print('I am online') print(bot.user.name) print(bot.user.id) print('-----') @bot.event async def on_message(message): # 过滤机器人自身消息 if message.author.bot: return # 处理前缀命令 await bot.process_commands(message) member = message.author # 角色ID改为整数类型 role = discord.utils.get(member.guild.roles, id=899279907216031744) splits = message.content.split("-") # 初始化cont为True,校验不通过时再改为False cont = True # 格式长度不符合直接终止后续校验 if len(splits) != 4: return # 检查首段是否为1-999范围内的数字 try: first_num = int(splits[0]) if first_num <= 0 or first_num >= 1000: cont = False except ValueError: cont = False # 检查第二段是否为指定值 if cont and splits[1] not in ["UG", "PG", "D"]: cont = False # 检查第三段是否为指定值 if cont and splits[2] not in ["CSAI","CSE","ECAI","ECE","IT","MAE","EEE","CE","PD","AE","CH","CE","EE","ME","ED","MV","ER","QT","RAS","AI","CS","CP","BE","CHE","CHEM","CG","CC","VLSI","EV","DES"]: cont = False # 检查第四段是否为2023及以后的数字 try: if cont and int(splits[3]) <= 2022: cont = False except ValueError: cont = False # 符合所有条件则分配身份组 if cont: await member.add_roles(role) bot.run(os.getenv('TOKEN'))
改动说明
- 开头新增机器人自身消息过滤逻辑,避免循环触发
- 新增
process_commands调用,保证前缀命令可以正常使用 - 角色ID去掉引号改为整数类型,正常匹配身份组
- 给cont添加初始值True,避免未定义错误
- 长度校验不通过直接return,避免后续索引越界
- 修正首段数字的判断逻辑和赋值逻辑,符合1-999的校验要求
- 后续校验前先判断cont状态,减少无效校验执行
- 身份组添加改为直接调用member实例的add_roles方法,写法更简洁规范
内容的提问来源于stack exchange,提问作者Soumyajoy Das
相关产品推荐
相关产品推荐

