discord.py经济机器人balance命令已定义却触发CommandNotFound错误
解决discord.py中
balance命令未找到的问题 我来帮你拆解这个CommandNotFound错误,以及代码里隐藏的其他问题,一步步帮你修复:
1. 命令未被识别的核心原因
最常见的问题是Bot实例的命令前缀不匹配或者装饰器使用不规范:
- 首先检查你的Bot初始化代码,必须明确指定命令前缀(比如
!),否则Bot不知道该响应什么格式的命令:from discord.ext import commands import discord import json # 必须启用message_content意图才能接收命令消息 intents = discord.Intents.default() intents.message_content = True # 这里的command_prefix要和你调用命令时用的前缀一致,比如用'!' client = commands.Bot(command_prefix='!', intents=intents) - 另外你代码里
balance函数的global user完全多余,而且user变量根本没定义,应该直接用ctx.author来获取发起命令的用户。
2. 修复open函数的逻辑错误
你的open函数有两个致命问题:
- 当用户不在
users字典中时,直接users[str(user.id)]["wallet"]=0会抛出KeyError——因为这个用户的键还不存在,得先创建完整的字典条目再赋值 - 重复读取JSON文件(先调用
get()又自己读一遍),容易导致数据不一致
修复后的open_account函数(改个更清晰的名字,避免和内置函数冲突):
async def open_account(user): users = await get_users() # 用户不存在则创建新的账户条目 if str(user.id) not in users: users[str(user.id)] = {"wallet": 0, "bank": 0} with open(r"C:\discbot\bank.json", "w") as data: json.dump(users, data, indent=4) # indent让JSON文件更易读 return True return False
3. 简化get_users函数
把原get函数改名,避免和内置函数重名:
async def get_users(): with open(r"C:\discbot\bank.json", "r") as data: return json.load(data)
4. 修复balance命令的代码
去掉无用的全局变量,正确调用账户初始化函数,优化Embed的显示:
@client.command() # 注意装饰器前面的@不能漏! async def balance(ctx): await open_account(ctx.author) users = await get_users() user_id = str(ctx.author.id) wallet_data = users[user_id]["wallet"] bank_data = users[user_id]["bank"] details = discord.Embed(title=f"{ctx.author.display_name}'s Balance", color=discord.Color.red()) details.add_field(name="💵 Wallet", value=f"${wallet_data}", inline=True) # inline=True让两个字段并排显示 details.add_field(name="🏦 Bank", value=f"${bank_data}", inline=True) await ctx.send(embed=details)
5. 其他关键注意事项
- 确保你的
bank.json初始内容是{}(空字典),否则第一次读取会报错 - 运行Bot前,确保安装了最新版discord.py:
pip install -U discord.py - 调用命令时要和你设置的前缀一致,比如你设了
!,就发!balance
完整修复后的代码示例
from discord.ext import commands import discord import json # 配置Bot的Intents和命令前缀 intents = discord.Intents.default() intents.message_content = True client = commands.Bot(command_prefix='!', intents=intents) async def get_users(): with open(r"C:\discbot\bank.json", "r") as data: return json.load(data) async def open_account(user): users = await get_users() if str(user.id) not in users: users[str(user.id)] = {"wallet": 0, "bank": 0} with open(r"C:\discbot\bank.json", "w") as data: json.dump(users, data, indent=4) return True return False @client.command() async def balance(ctx): await open_account(ctx.author) users = await get_users() user_id = str(ctx.author.id) wallet = users[user_id]["wallet"] bank = users[user_id]["bank"] embed = discord.Embed(title=f"{ctx.author.display_name}'s Balance", color=discord.Color.red()) embed.add_field(name="💵 Wallet", value=f"${wallet}", inline=True) embed.add_field(name="🏦 Bank", value=f"${bank}", inline=True) await ctx.send(embed=embed) # 替换成你的Bot Token client.run("YOUR_BOT_TOKEN_HERE")
现在用!balance(对应你设置的命令前缀)调用命令,应该就能正常显示余额了。
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

