You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord.py调用ctx.author.id触发AttributeError报错排查

报错根因

代码存在4个直接触发运行异常的问题:

  • 参数传递逻辑错误:balance命令调用o_acc时传入的是ctx.author(Discord的Member用户对象),但o_acc函数内部还在尝试访问ctx.author.id,相当于在Member对象上查找不存在的author属性,直接触发你看到的AttributeError。
  • async/await语法乱用:o_acc、gbd两个函数没有加async关键字声明,函数内部和调用位置却随意添加await,会触发协程对象相关报错;且json模块的文件读写是同步操作,本身不需要await。
  • 字段名大小写不匹配:写入用户余额时用的键名是大写开头的"Wallet",查询余额时用的是全小写的"wallet",就算前面的错误修复完成,这里也会触发KeyError。
  • 缺少文件初始化逻辑:首次运行程序时如果目录下没有user.json文件,直接读取文件会报文件不存在错误。
修复后可运行代码
from discord.ext import commands
import discord
import json
import os
from keep_alive import keep_alive

bot = commands.Bot(command_prefix='.')

# 封装读用户数据方法,补全文件不存在的初始化逻辑
def get_bank_data():
    # 首次运行无user.json时自动创建空数据文件
    if not os.path.exists("user.json"):
        with open("user.json", "w") as f:
            json.dump({}, f)
    with open("user.json", "r") as f:
        users = json.load(f)
    return users

# 开户逻辑,参数直接接收用户对象
async def open_account(user):
    users = get_bank_data()
    user_id = str(user.id)
    if user_id in users:
        return False
    # 统一用小写wallet作为键名,和查询逻辑对齐
    users[user_id] = {"wallet": 10000}
    with open("user.json", "w") as f:
        json.dump(users, f)
    return True

# 余额查询命令
@bot.command(name='bal')
async def balance(ctx):
    # 传入当前触发命令的用户完成开户检查
    await open_account(ctx.author)
    users = get_bank_data()
    user_id = str(ctx.author.id)
    # 构造余额嵌入消息
    em = discord.Embed(title=f"{ctx.author.name}'s balance")
    em.add_field(name='Wallet balance', value=users[user_id]['wallet'])
    await ctx.send(embed=em)

keep_alive()
# 替换为你自己的机器人真实Token
bot.run('你的机器人Token')
补充说明
  • 已删除未使用的random、asyncio冗余导入,减少不必要的资源占用。
  • 所有用户数据读写逻辑统一字段名,不会再出现键名不匹配问题。
  • 首次运行会自动创建user.json文件,不需要手动提前新建。

内容的提问来源于stack exchange,提问作者Odejeve64

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 01:54:28