Python Discord Bot:注册后无法使用dig命令,JSON同步异常
已注册但执行.dig命令仍提示未注册的排查与修复
核心问题定位
你的.dig命令使用了@checks.has_registered()装饰器,这个装饰器会在命令执行前优先触发注册状态检查,优先级远高于你在dig函数内部写的if user_id in registered:判断。也就是说,即使你手动在函数里做了校验,装饰器已经提前拦截了命令并返回未注册提示,根本没走到后续逻辑。
问题的根源几乎肯定在helpers/checks.py中的has_registered装饰器实现上,比如:
- 装饰器读取的注册文件路径与
register.py不一致 - 装饰器中判断用户ID的类型错误(比如用整数ID匹配字符串ID)
- 装饰器的文件读取逻辑存在异常处理漏洞
排查与修复步骤
1. 检查has_registered装饰器代码
确保装饰器的逻辑和register.py完全对齐,以下是标准的正确实现参考:
from discord.ext import commands import json import os import discord class NotStarted(commands.CheckFailure): def __init__(self, embed): self.embed = embed super().__init__() def has_registered(): async def predicate(ctx): user_id = str(ctx.author.id) registered_file = "data/registered.json" # 确保文件路径正确,与register.py一致 if not os.path.exists(registered_file): embed = discord.Embed( title="未注册", description="请先使用.reg命令注册账号!", color=discord.Color.red() ) raise NotStarted(embed) # 读取注册数据,处理JSON解码异常 with open(registered_file, "r") as f: try: registered_data = json.load(f) except json.JSONDecodeError: registered_data = {} # 用字符串ID匹配(与register.py存储的类型一致) if user_id not in registered_data: embed = discord.Embed( title="未注册", description="请先使用.reg命令注册账号!", color=discord.Color.red() ) raise NotStarted(embed) return True return commands.check(predicate)
2. 验证路径与类型一致性
- 确认装饰器中读取的
registered.json路径和register.py完全相同(比如都是data/registered.json,注意机器人启动目录与data文件夹的相对位置) - 确保装饰器中用户ID用
str(ctx.author.id)转换为字符串,和register.py中存储的ID类型一致
3. 临时测试方案
如果暂时无法修改装饰器,可以先注释掉@checks.has_registered()这一行,再执行.dig命令:
# @checks.has_registered() # 先注释掉 @commands.hybrid_command(aliases=["mine"], name="dig", description="Dig for coins in the earth!") @commands.cooldown(1, 10, commands.BucketType.user) async def dig(self, ctx): # ... 原有逻辑 ...
如果此时命令能正常执行,就彻底确认是装饰器的问题。
代码优化建议
把重复的load_data和save_data函数抽离到公共模块,避免多文件逻辑不一致:
- 创建
helpers/utils.py:
import json import os def load_data(file_path): if not os.path.exists(file_path): return {} with open(file_path, "r") as f: try: return json.load(f) except json.JSONDecodeError: return {} def save_data(file_path, data): # 自动创建data文件夹,避免路径不存在报错 os.makedirs(os.path.dirname(file_path), exist_ok=True) with open(file_path, "w") as f: json.dump(data, f, indent=2)
- 在
register.py和dig.py中统一导入:
from helpers.utils import load_data, save_data
内容的提问来源于stack exchange,提问作者Kurtis
相关产品推荐
相关产品推荐

