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

Python3.10+Discord.py2.0:扩展模块装饰器复用主模块配置值

解决方案

针对你遇到的「将config中的Guild ID传入Cog装饰器且不重复读取配置」的问题,有两种实用方案:

方案一:在setup函数中动态配置命令的Guild范围

装饰器在类定义阶段就会执行,此时__init__还未初始化,无法直接通过bot.config获取值。但setup函数在加载Cog时执行,此时已能访问bot实例,可通过动态修改命令属性实现需求:

修改cogs/extension.py:

from discord import app_commands
from discord.ext import commands

class MyCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @app_commands.command(name='mycommand')
    # 移除原有的@app_commands.guilds()装饰器
    async def command(self, interaction):
        # 执行命令逻辑
        await interaction.response.send_message("命令执行成功")

async def setup(bot):
    cog = MyCog(bot)
    # 从bot实例获取配置中的Guild ID,转为discord.Object
    target_guild = app_commands.Object(id=int(bot.config['guild_id']))
    # 给指定命令添加Guild范围
    cog.command.guilds.append(target_guild)
    
    # 若Cog中有多个命令,可批量处理:
    # for cmd in cog.walk_app_commands():
    #     cmd.guilds.append(target_guild)
    
    await bot.add_cog(cog)

方案二:将配置抽为独立模块(更优雅)

把配置读取逻辑单独放在一个模块中,整个项目仅读取一次配置,所有模块直接导入使用,避免装饰器阶段无法访问bot实例的问题:

  1. 创建config.py文件:
import json

# 仅读取一次配置
with open('config.json', 'r') as f:
    config = json.load(f)
  1. 修改main.py:
from config import config
import discord
from discord.ext import commands
import os
import asyncio

bot = commands.Bot(prefix='!', intents=discord.Intents.all())
bot.config = config  # 保留这行以便Cog中仍能通过bot访问(可选)

async def load_cogs():
    for filename in os.listdir('cogs/'):
        if filename.endswith('.py'):
            await bot.load_extension(f'cogs.{filename[:-3]}')

async def main():
    await load_cogs()
    await bot.start(bot.config['TOKEN'])  # 这里也可以直接用config['TOKEN']

asyncio.run(main())
  1. 修改cogs/extension.py:
from config import config
from discord import app_commands
from discord.ext import commands

class MyCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @app_commands.command(name='mycommand')
    # 直接从config模块获取Guild ID
    @app_commands.guilds(app_commands.Object(id=int(config['guild_id'])))
    async def command(self, interaction):
        # 执行命令逻辑
        await interaction.response.send_message("命令执行成功")

async def setup(bot):
    await bot.add_cog(MyCog(bot))

注意事项

  • 确保config.json中的guild_id是字符串或可转为整数的类型,discord.Object需要传入整数ID。
  • 方案一无需调整项目结构,适合小型项目;方案二配置集中管理,更利于大型项目维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 17:40:29