齿轮

在你开发机器人的过程中,你可能会想要将命令、监听器、或者某些状态包装到一个类里面,齿轮(Cog)就可以让你做到这一点。

大概原理:

齿轮一般会与 扩展 一起使用。

快速示例

这个示例 cog 为你的命令定义了一个 Greetings 类别,带有一个名为 hello命令 以及一个监听 事件

class Greetings(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self._last_member = None

    @commands.Cog.listener()
    async def on_ready(self):
        print(f'以 {self.bot.user} 身份登录(ID:{self.bot.user.id})')
        print('------')

    @commands.command()
    async def hello(self, ctx, *, member: qq.Member = None):
        """说你好"""
        member = member or ctx.author
        if self._last_member is None or self._last_member.id != member.id:
            await ctx.send(f'你好{member.name}~')
        else:
            await ctx.send(f'你好{member.name}... 这感觉很熟悉。')
        self._last_member = member

需要考虑的几个技术说明:

  • 所有监听器都必须通过 listener() 装饰器显式标记。

  • 齿轮的名称默认为类名,但和命令一样可以覆盖。 参见 元选项

  • 所有命令都必须采用 self 参数。

齿轮注册

一旦你定义了你的齿轮,你需要告诉机器人注册要使用的齿轮。 我们通过 add_cog() 方法来做到这一点。

bot.add_cog(Greetings(bot))

这会将齿轮绑定到机器人,自动将所有命令和监听器添加到机器人。

请注意,我们可以通过名称引用齿轮,名称可以通过 元选项 覆盖。 如果我们最终想要移除齿轮,我们将执行以下操作。

bot.remove_cog('Greetings')

使用齿轮

就像我们通过名字移除一个齿轮一样,我们也可以通过它的名字来检索它。 这允许我们使用齿轮作为命令间通信协议来共享数据。 例如:

class Economy(commands.Cog):
    ...

    async def withdraw_money(self, member, money):
        # 在这里实现
        ...

    async def deposit_money(self, member, money):
        # 在这里实现
        ...

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

    def coinflip(self):
        return random.randint(0, 1)

    @commands.command()
    async def gamble(self, ctx, money: int):
        """赌点钱。"""
        economy = self.bot.get_cog('Economy')
        if economy is not None:
            await economy.withdraw_money(ctx.author, money)
            if self.coinflip() == 1:
                await economy.deposit_money(ctx.author, money * 1.5)

特殊方法

随着齿轮变得越来越复杂并拥有更多命令,我们需要自定义整个齿轮或机器人的行为。

它们如下:

你可以访问参考资料以获取更多详细信息。

元选项

齿轮的核心是一个元类,commands.CogMeta,它可以采用各种选项来定制一些行为。 要做到这样,我们将关键字参数传递给类定义行。 例如,要更改齿轮名称,我们可以传递 name 关键字参数,如下所示:

class MyCog(commands.Cog, name='我的第一个齿轮'):
    pass

要查看你可以设置的更多选项,请参阅 commands.CogMeta 的文档。

检查

由于齿轮是类,因此我们有一些工具可以帮助我们检查齿轮的某些属性。

要获取命令的 list,我们可以使用 Cog.get_commands()

>>> cog = bot.get_cog('Greetings')
>>> commands = cog.get_commands()
>>> print([c.name for c in commands])

如果我们也想获得子命令,我们可以使用 Cog.walk_commands() 生成器。

>>> print([c.qualified_name for c in cog.walk_commands()])

要对监听器执行相同操作,我们可以使用 Cog.get_listeners() 查询它们。 这将返回一个元组列表,第一个元素是监听器名称,第二个元素是实际的函数本身。

>>> for name, func in cog.get_listeners():
...     print(name, '->', func)