Discord机器人Cog文件无法定位同目录prefixes.json文件问题求助
问题修复方案
核心错误原因
- 相对路径读取逻辑错误:Python的相对路径以运行脚本时的工作目录为基准,而非代码文件本身的存放目录,你在Cog中硬编码
prefixes.json相对路径会因启动目录不同找不到文件 - Cog结构缩进错误:
change_prefix命令、on_guild_remove监听器均未缩进在Prefixes类内部,导致功能未被注册,加载Cog后直接失效 - 语法错误:权限装饰器写法错误、Cog加载命令变量拼接错误、类方法缺失
self参数 - 重复实例化Bot对象:Cog中重复定义
client = commands.Bot(...)和主文件的Bot实例冲突 - 缺失JSON文件初始化逻辑:首次运行如果
prefixes.json不存在会直接抛出文件缺失错误
具体修复步骤
1. 统一JSON文件绝对路径
在Cog文件(Prefix_changer.py)开头新增路径生成和初始化逻辑,彻底解决路径读取问题:
import discord import logging import json import os from discord.ext import commands # 新增:基于当前Cog文件路径生成prefixes.json的绝对路径 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) PREFIX_FILE_PATH = os.path.join(BASE_DIR, 'prefixes.json') # 新增:初始化JSON文件,不存在则自动创建空对象 def init_prefix_file(): if not os.path.exists(PREFIX_FILE_PATH): with open(PREFIX_FILE_PATH, 'w', encoding='utf-8') as f: json.dump({}, f) init_prefix_file()
所有后续读取/写入JSON的代码,都把'prefixes.json'替换为PREFIX_FILE_PATH变量。
2. 修正Cog结构和语法错误
修正后的完整Cog代码如下:
class Prefixes(commands.Cog): def __init__(self, client): self.client = client # 新增self参数,缩进对齐到类内部 @commands.Cog.listener() async def on_guild_join(self, guild): with open(PREFIX_FILE_PATH, 'r', encoding='utf-8') as f: prefixes = json.load(f) prefixes[str(guild.id)] = '.' with open(PREFIX_FILE_PATH, 'w', encoding='utf-8') as f: json.dump(prefixes, f, indent = 4) # 缩进对齐到类内部,新增self参数,修正权限装饰器写法 @commands.command() @commands.has_role("admin") async def change_prefix(self, ctx, prefix): with open(PREFIX_FILE_PATH, 'r', encoding='utf-8') as f: prefixes = json.load(f) prefixes[str(ctx.guild.id)] = prefix with open(PREFIX_FILE_PATH, 'w', encoding='utf-8') as f: json.dump(prefixes, f, indent = 4) await ctx.send(f'Prefix changed to: {prefix}') # 缩进对齐到类内部,新增装饰器和self参数 @commands.Cog.listener() async def on_guild_remove(self, guild): with open(PREFIX_FILE_PATH, 'r', encoding='utf-8') as f: prefixes = json.load(f) prefixes.pop(str(guild.id), None) # 加None避免不存在时报错 with open(PREFIX_FILE_PATH, 'w', encoding='utf-8') as f: json.dump(prefixes, f, indent= 4) # 移出类外的get_prefix保持不变,替换文件路径即可 def get_prefix(client, message): # 容错:私聊返回默认前缀,无对应服务器配置也返回默认前缀 if not message.guild: return '.' with open(PREFIX_FILE_PATH, 'r', encoding='utf-8') as f: prefixes = json.load(f) return prefixes.get(str(message.guild.id), '.') # 删掉Cog中重复的client实例化代码!! # Connects Cog to bot def setup(client): client.add_cog(Prefixes(client))
3. 修正主文件错误
把主文件中load/unload命令的变量拼接错误修正:
# 修正前是f'cogs.[extension]',把方括号改成大括号 @client.command() async def load(ctx, extension): client.load_extension(f'cogs.{extension}') @client.command() async def unload(ctx, extension): client.unload_extension(f'cogs.{extension}')
验证操作
- 删除之前手动移动的所有prefixes.json文件,让脚本自动在cogs目录下生成新的JSON文件
- 重启机器人,加入测试服务器会自动写入默认前缀
. - 使用admin身份执行
.change_prefix $即可测试前缀修改功能
内容的提问来源于stack exchange,提问作者Vincent
相关产品推荐
相关产品推荐

