Discord.py Cog函数调用及variables Cog优先加载方案咨询
解决方案
1. 保证variables Cog优先加载
原遍历目录加载Cog的逻辑无法控制加载顺序,修改加载逻辑:先主动加载variables,再遍历加载剩余Cog,同时删除原on_ready中强制导入调用的冗余代码,修正后main.py代码如下:
import discord import os from discord.ext import commands intents = discord.Intents.default() intents.members = True intents.guilds = True bot = commands.Bot(command_prefix=',', intents=intents) # 自定义Cog加载逻辑,优先加载variables async def load_cogs(): # 第一步强制优先加载variables await bot.load_extension('cogs.variables') # 再加载其他所有Cog,跳过已加载的variables for filename in os.listdir('./cogs'): if filename.endswith('.py') and filename[:-3] != 'variables': await bot.load_extension(f'cogs.{filename[:-3]}') @bot.event async def on_ready(): print(f'The bot has logged in as {bot.user}') print('''LOADING COGS:---''') # 修复Cog管理指令,discord.py 2.0+ 版本加载方法为异步需加await @bot.command() async def load(ctx, extension): await bot.load_extension(f'cogs.{extension}') await ctx.send(f'loaded {extension}') @bot.command() async def reload(ctx, extension): await bot.reload_extension(f'cogs.{extension}') await ctx.send(f'reloaded {extension}') @bot.command() async def unload(ctx, extension): await bot.unload_extension(f'cogs.{extension}') await ctx.send(f'unloaded {extension}') # 启动入口 async def main(): async with bot: await load_cogs() await bot.run('TOKEN') # 替换为自己的Bot Token if __name__ == '__main__': import asyncio asyncio.run(main())
如果使用discord.py 1.x版本,删除所有加载方法前的await,把load_cogs改为同步函数直接调用即可。
2. 实现test5的双场景调用
原有代码存在类方法缺少self参数、指令缺失必填ctx参数、滥用全局变量、跨文件导入Bot容易触发循环导入的问题,修正思路为:
- 把variables中的公共属性改为Cog实例属性,通过
bot.get_cog()获取实例调用,避免全局变量 - 将test5核心逻辑抽离为无额外参数的内部方法,同时支持指令触发和
on_ready内直接调用 - 所有Cog内直接使用
self.bot获取Bot实例,避免跨文件导入
修正后cogs/variables.py代码:
import discord from discord.ext import commands class variables(commands.Cog): def __init__(self, bot): self.bot = bot self.guild_id = 123456789 # 替换为自己的服务器ID self.guild = None # 公共属性代替全局变量 async def primaries(self): print('primaries') self.guild = discord.utils.find(lambda g : g.id == self.guild_id, self.bot.guilds) @commands.Cog.listener() async def on_ready(self): await self.primaries() def setup(bot): bot.add_cog(variables(bot))
修正后cogs/test.py代码:
from discord.ext import commands class test(commands.Cog): def __init__(self, bot): self.bot = bot # 核心逻辑抽离,无额外参数,支持任意场景调用 async def _test5_core(self): variables_cog = self.bot.get_cog('variables') print(variables_cog.guild) # 指令装饰器,用户输入`,test5`即可触发 @commands.command() async def test5(self, ctx): await self._test5_core() @commands.Cog.listener() async def on_ready(self): # on_ready中直接调用核心逻辑,无需传ctx await self._test5_core() def setup(bot): bot.add_cog(test(bot))
内容的提问来源于stack exchange,提问作者omar
相关产品推荐
相关产品推荐

