【问题标题】:How do I use cogs with discord.py?如何在 discord.py 中使用 cogs?
【发布时间】:2019-04-30 21:01:05
【问题描述】:

我为 Discord 编写了一个相当大的机器人。它有超过 1000 行代码。当我在 Youtube 和这里​​研究如何做到这一点时,似乎没有任何效果。我想知道是否有人可以解释如何正确使用齿轮,可能还有照片示例。我可以展示我必须使用的代码来帮助您理解我想要什么。

举个例子,我想将我所有的 mod 命令放在一个单独的文件中,这样它就更干净、更有条理了。那么,我该怎么做呢?这是我的代码示例:

Mod 命令我想使用 cog 移动到单独的文件

我目前拥有的进口商品

前缀和目录

调用令牌 ID - 令牌 ID 在上面,图中未显示:

我不确定如何完全启动一个 cog,还要导入什么,如何调用文件。我很了解 Java,但我正在尝试使用 Discord 来提高我的 Python 技能。

【问题讨论】:

    标签: python bots discord discord.py


    【解决方案1】:

    注意:

    以下内容是为较旧的 0.16 版本编写的,该版本没有良好的 cogs 文档。新的 1.0 版本有很好的文档,并且完全改变了 cogs 的结构。如果您使用的是现代版本的,您应该咨询official documentation

    简介

    每个 cog 都有两部分:一个类和一个setup 函数。几乎所有setup 函数看起来都一样:

    def setup(bot):
        bot.add_cog(Cog(bot))
    

    Cog 是 cog 类。

    cog 类包含我们所有的命令和事件作为方法。

    主要变化

    您需要进行四个主要的转换才能将您的机器人变成一个齿轮:

    1. bot.command 替换为commands.commandcommandsfrom discord.ext import commands

    2. 更改函数的签名以在开头包含 self,因为您的所有命令和事件现在都是 cog 类的方法

    3. 将所有对bot的引用改为引用self.bot

    4. 删除所有 bot.event 装饰器。您的 cog 中的事件侦听器仅在名称上注册

    还有一些陷阱:

    1. 从 cog 中的任何 on_message 事件中删除 await bot.process_commands(message)。对于任何消息,这应该只等待一次。默认的on_message 已经为您完成了这项工作。

    2. 通过 cog 注册事件不会从您的主文件或其他 cog 中删除与该事件相关的其他回调。这意味着您的机器人可以多次响应 on_member_join 事件,例如,如果您在多个位置定义了该事件的行为。

    示例

    假设您在目录src 中有以下discord.py 机器人bot.py

    from discord.ext import commands
    
    bot = commands.Bot(command_prefix='!')
    
    @bot.command(pass_context=True)
    @commands.has_role("Mod")
    async def acommand(ctx, argument):
       await bot.say("Stuff")
    
    @bot.event
    async def on_message(message):
        print(message.content)
        await bot.process_commands(message)
    
    bot.run("token")
    

    然后您将该功能分解为一个 cog src/cogs/maincog.py

    from discord.ext import commands
    
    class MainCog:
        def __init__(self, bot):
            self.bot = bot
    
        @commands.command(pass_context=True)
        @commands.has_role("Mod")
        async def acommand(self, ctx, argument):
           await self.bot.say("Stuff")        
    
        async def on_message(self, message):
            print(message.content)
    
    def setup(bot):
        bot.add_cog(MainCog(bot))
    

    你的bot.py 文件看起来像

    from discord.ext import commands
    
    bot = commands.Bot(command_prefix='!')
    
    bot.load_extension("cogs.maincog")
    
    bot.run("token")
    

    请注意,要在cogs/maincog.py 加载扩展,我们使用load_extension("cogs.maincog")

    其他功能

    Cogs 还允许你定义一些特殊的方法。其中大部分仅在 中可用,并记录在here

    1. __global_check,以前的 __check,在每个命令之前运行,并且必须返回 True 才能继续执行该命令。

    2. __local_check 仅在来自此 cog 的命令之前运行。

    3. __global_check_once 我相信这类似于__global_check,只是它只在子命令的情况下检查一次。我没用过这么多。

    4. __unload 您可以通过卸载扩展程序,然后重新加载它来实时刷新您的机器人,这样您就可以在不让机器人离线的情况下更新您的 cogs。当您卸载扩展程序或当您的机器人停止运行时调用此方法,以防您需要进行清理。

    5. __before_invoke__after_invoke 分别在来自该 cog 的每个命令之前和之后运行。

    6. __error 是来自此 cog 的命令的错误处理程序。

    【讨论】:

    • 非常感谢!这有很大帮助,我能够让它工作!!! @Patrick Haugh
    • 请注意,这个答案已经过时了。查看docs 以获取当前信息。
    【解决方案2】:

    一个基本的 cog 模板如下所示:

    import discord
    import asyncio
    from discord.ext import commands
    
    class cog_name(commands.Cog):
        def __init__(self, bot):
            self.bot = bot
    
    def setup(bot):
        bot.add_cog(cog_name(bot))
    

    为了将这个 cog 添加到你的机器人,在你的主文件中,添加这个:

    client.load_extension('script_name')
    

    如果 cog 脚本在文件夹中,

    client.load_extension('folder_name.script_name')
    

    【讨论】:

    • 如果我将客户端用作@client 装饰器会怎样。
    • 我该如何适应客户
    • 因为 cog 是 commands.Cog 类的实例并且客户端不在同一个脚本中,所以您必须使用 @commands.command()
    猜你喜欢
    • 2021-04-19
    • 1970-01-01
    • 2020-12-12
    • 2020-11-13
    • 2019-09-21
    • 1970-01-01
    • 1970-01-01
    • 2020-09-27
    • 1970-01-01
    相关资源
    最近更新 更多