discord.py使用json模块触发ValueError循环引用报错的解决方法
Discord机器人欢迎频道设置错误修复方案
错误根因
你遇到的ValueError: Circular reference detected报错完全由变量重名导致:
changewelcomechannel命令的入参名设置为welcomechannel,用来接收用户传入的新频道参数- 后续读取JSON配置文件时,你又将解析得到的配置字典赋值给了同名的
welcomechannel变量,直接覆盖了用户传入的参数值 - 执行
welcomechannel[str(ctx.guild.id)] = welcomechannel语句时,等于将配置字典本身赋值给自身的键,形成了循环引用的嵌套结构,JSON序列化时无法解析这种结构就会抛出错误。
除此之外你的代码还存在两个隐藏问题:
on_guild_join事件中,更新完欢迎频道配置后错误写入到了prefixes.json文件,导致欢迎频道配置根本没有保存changewelcomechannel命令末尾的await ctx.send语句缺少右括号,运行时会触发语法错误
修复后的代码
1. 修复on_guild_join事件
@client.event async def on_guild_join(guild): # 补充discord.utils调用,原代码直接用find会报错 general = discord.utils.find(lambda x: x.name == 'general', guild.text_channels) if general and general.permissions_for(guild.me).send_messages: await general.send(f'Hello {guild.name}! My name is {client.user.name} and my prefix is `?`! run `?help` to begin using me!') with open('prefixes.json', 'r') as f: prefixes = json.load(f) prefixes[str(guild.id)] = "?" with open ('prefixes.json', 'w') as f: json.dump(prefixes, f, indent=4) with open('welcomechannel.json', 'r') as f: welcomechannel = json.load(f) welcomechannel[str(guild.id)] = "general" # 修正写入的目标文件 with open ('welcomechannel.json', 'w') as f: json.dump(welcomechannel, f, indent=4)
2. 修复changewelcomechannel命令
@client.command(name="changewelcomechannel") # 入参改名避免重名,同时用discord自带的TextChannel转换器直接接收频道对象,使用更方便 async def changewelcomechannel(ctx, new_welcome_channel: discord.TextChannel): with open('welcomechannel.json', 'r') as f: welcome_config = json.load(f) # 推荐存储频道ID而非名称,避免频道改名后配置失效 welcome_config[str(ctx.guild.id)] = new_welcome_channel.id with open ('welcomechannel.json', 'w') as f: json.dump(welcome_config, f, indent=4) # 补全右括号,用频道提及符更直观 await ctx.send(f"欢迎频道已设置为 **{new_welcome_channel.mention}**!")
可选优化:修改get_welcomechannel方法适配频道ID存储
def get_welcomechannel(client, message): with open('welcomechannel.json', 'r') as f: welcome_config = json.load(f) # 用存储的频道ID直接获取频道对象,不用遍历查找 return message.guild.get_channel(int(welcome_config[str(message.guild.id)]))
内容的提问来源于stack exchange,提问作者Aadit John
相关产品推荐
相关产品推荐

