Discord.py经济机器人报AttributeError: 'dict'对象无id属性
错误成因
你看到的discord.ext.commands.errors.CommandInvokeError是discord.py命令框架的通用封装异常,所有命令执行过程中抛出的未捕获异常都会被包装成这个错误抛出,不是问题根因。
核心报错来自open_account函数接收到的user参数实际为字典类型,而非预期的discord.Member/discord.User实例对象,因此访问.id属性时触发AttributeError。
该问题绝大多数是以下两种错误写法导致:
- 调用
open_account时传参错误:误将读取MainBank.json得到的用户存储字典、或其他字典类型变量传入函数,没有传入触发命令的用户对象ctx.author - 函数参数顺序定义错误:比如给
open_account额外加了ctx参数且放在参数列表第一位,调用时仅传入用户对象,导致参数错位,本该接收用户对象的形参取到了其他字典值
修复方案
按以下步骤逐一修正即可:
- 重构
open_account及配套的文件读写逻辑,确保函数参数仅接收用户对象,不要混入上下文参数,参考实现如下:
import json import discord from discord.ext import commands # 抽离通用的银行数据读写逻辑,避免重复代码 async def load_bank_data(): with open("MainBank.json", "r", encoding="utf-8") as f: return json.load(f) async def write_bank_data(data: dict): with open("MainBank.json", "w", encoding="utf-8") as f: json.dump(data, f, indent=4, ensure_ascii=False) async def open_account(user: discord.Member | discord.User): users = await load_bank_data() user_id = str(user.id) # 新用户自动初始化账户 if user_id not in users: users[user_id] = { "wallet": 0, "bank": 0 } await write_bank_data(users) return True
- 全局搜索所有调用
open_account的位置,确保传入的参数固定为ctx.author(即触发命令的服务器成员对象),禁止传入任何字典类型值,正确的命令调用示例:
@bot.command(name="balance", aliases=["余额"]) async def check_balance(ctx): # 确保用户已开户,此处必须传ctx.author await open_account(ctx.author) users = await load_bank_data() user_data = users[str(ctx.author.id)] embed = discord.Embed(title=f"{ctx.author.name}的资产") embed.add_field(name="钱包余额", value=user_data["wallet"]) embed.add_field(name="银行存款", value=user_data["bank"]) await ctx.send(embed=embed)
- 检查
MainBank.json初始格式是否合法,首次运行时文件内直接写空字典{}即可,不要写其他非法结构,后续用户开户会自动写入对应数据。 - 保存修改后重启机器人,执行命令即可恢复正常。
内容的提问来源于stack exchange,提问作者64Del101
相关产品推荐
相关产品推荐

