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

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函数抽离到公共模块,避免多文件逻辑不一致:

  1. 创建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)
  1. 在register.py和dig.py中统一导入:
from helpers.utils import load_data, save_data

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 18:40:55