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

Discord Bot多文件导入命令仅同步最后一个文件问题求助

问题原因

你遇到的核心问题是每个cog文件都重新实例化了commands.Bot对象。当你用from ... import *导入这些文件时,后面文件里的client实例会覆盖前面所有导入的client,最终只有最后一个文件的client被保留,同步命令时自然只会同步它的命令。

解决方案

按照discord.py的标准Cog规范改造你的代码,统一使用主文件的client实例注册命令:

1. 改造单个Cog文件(以admin.py为例)

删除Cog文件里的client实例创建代码,改用commands.Cog类组织命令:

import discord
from discord import app_commands
from discord.ext import commands

class Admin(commands.Cog):
    def __init__(self, client):
        self.client = client

    @app_commands.command(name="say", description="让机器人发送指定内容")
    @app_commands.describe(say="要发送的文本内容")
    async def say(self, interaction: discord.Interaction, say: str):
        if not interaction.user.guild_permissions.administrator:
            return await interaction.response.send_message("你不是管理员,无法使用此命令。")
        await interaction.response.send_message(f'{say}')

    # 如果需要Cog内的就绪事件,用listener装饰器
    @commands.Cog.listener()
    async def on_ready(self):
        print(f"[Admin模块] 已就绪")

async def setup(client):
    await client.add_cog(Admin(client))

2. 改造main.py文件

统一创建client实例,使用load_extension加载所有Cog,而非直接导入:

import discord
from discord.ext import commands
import asyncio

# 初始化主客户端
intents = discord.Intents.all()
client = commands.Bot(command_prefix='.', intents=intents)
client.remove_command('help')

@client.event
async def on_ready():
    print("机器人已就绪,可以关闭此标签页")
    embed = discord.Embed(colour=discord.Colour.blue())
    channel = client.get_channel(你的频道ID)  # 替换为实际频道ID
    embed.add_field(name=f'重新上线',
                    value='机器人已完成更新',
                    inline=False)
    await channel.send(embed=embed)
    try:
        synced = await client.tree.sync()
        print(f"已同步 {len(synced)} 条命令")
    except Exception as e:
        print(e)

# 批量加载所有Cog
async def load_cogs():
    cogs_list = [
        "cogs.admin",
        "cogs.data",
        "cogs.economy",
        "cogs.fun",
        "cogs.gambling",
        "cogs.help",
        "cogs.inventory",
        "cogs.leveling",
        "cogs.market",
        "cogs.polls",
        "cogs.role_colors",
        "cogs.shop",
        "cogs.warnings",
        "cogs.xp_boosters"
    ]
    for cog in cogs_list:
        try:
            await client.load_extension(cog)
            print(f"已加载模块: {cog}")
        except Exception as e:
            print(f"加载模块 {cog} 失败: {str(e)}")

# 启动机器人
async def main():
    await load_cogs()
    await client.start("你的机器人令牌")  # 替换为实际令牌

if __name__ == "__main__":
    asyncio.run(main())
关键说明
  • 所有Cog共享同一个client实例,不会出现覆盖问题,所有命令都会被注册到客户端的命令树中。
  • setup函数是discord.py识别Cog的标准入口,必须实现。
  • 使用load_extension加载Cog是官方推荐的方式,便于管理模块的加载、卸载和重载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:45:11