Discord.py如何在cog加载/重载时执行cog内部的指定函数
解决方案
完全不需要使用eval这种不安全的方法,仅通过Discord.py内置API和getattr就可以实现需求,具体实现如下:
核心逻辑
- 调用
bot.reload_extension后,通过bot.get_cog(extension)可以直接拿到加载完成的Cog实例(注意这里的参数需要和你定义的Cog类名完全匹配,你示例中Cog类名为test和扩展名一致,所以可以直接传extension参数) - 用
getattr从Cog实例中取出你要执行的目标方法,方法名按照你的命名规则拼接即可 - 校验方法存在后,直接
await调用,传入要求的参数即可
可直接运行的代码示例
修改你的main.py中的重载命令如下:
@bot.command() async def reload(ctx, extension): try: bot.reload_extension(f'cogs.{extension}') await ctx.send(f'reloaded {extension}') # 获取加载后的Cog实例 target_cog = bot.get_cog(extension) if not target_cog: await ctx.send(f"未找到名为{extension}的Cog") return # 拼接方法名,获取对应方法 func_name = f"{extension}Reload" target_func = getattr(target_cog, func_name, None) if not target_func: await ctx.send(f"Cog {extension}中未找到{func_name}方法") return # 异步调用方法,传入ctx参数 await target_func(ctx) except Exception as e: await ctx.send(f"重载失败:{str(e)}")
可选优化建议
- 如果
xxxReload方法不需要作为用户可调用的公开命令,可以去掉@commands.command()装饰器,改为普通异步方法,避免用户主动触发 - 可以统一所有Cog的重载回调方法名为固定名称(比如统一叫
on_reload),不需要按照扩展名拼接,逻辑更简洁不容易出错
内容的提问来源于stack exchange,提问作者omar
相关产品推荐
相关产品推荐

