Cogs

봇의 개발 중 명령어들의 모음, 리스너, 그리고 몇몇 state들을 한 클래스에 조직화하고 싶을 때가 옵니다. Cogs는 그것을 할 수 있게 해줍니다.

요점:

일반적으로 cogs가 확장 와 함께 사용된다는 점을 참고해야 합니다.

간단한 예제

이 예제는 당신의 커맨드에 hello 라는 이름의 단일 commandEvent 를 감지하기 위한 리스너와 함께 Greetings 카테고리를 정의합니다.

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

    @commands.Cog.listener()
    async def on_member_join(self, member):
        channel = member.guild.system_channel
        if channel is not None:
            await channel.send('Welcome {0.mention}.'.format(member))

    @commands.command()
    async def hello(self, ctx, *, member: discord.Member = None):
        """Says hello"""
        member = member or ctx.author
        if self._last_member is None or self._last_member.id != member.id:
            await ctx.send('Hello {0.name}~'.format(member))
        else:
            await ctx.send('Hello {0.name}... This feels familiar.'.format(member))
        self._last_member = member

고려해야 할 몇 가지 기술적 참고 사항:

  • 모든 리스너들은 명시적으로 listener() 데코레이터를 통해 표시되어야만 합니다.

  • Cog의 이름은 자동적으로 클래스 이름에서 불러오지만, 덮어씌워질 수 있습니다. 메타 옵션 를 참고하세요.

  • 모든 명령어들은 이제 상태를 유지하는데 사용될 수 있는 인스턴스 속성들을 사용할 수 있게 self 파라미터를 사용해야 합니디.

Cog 등록

일단 cogs를 정의했다면, 당신은 cogs를 사용하기 위해 봇에게 등록하라고 해야 합니다. 우리는 이것을 add_cog() 메소드를 통해 수행합니다.

bot.add_cog(Greetings(bot))

이것은 cog를 봇으로 묶으며, 모든 커맨드들과 리스너들은 봇에 자동적으로 추가됩니다.

우리가 cog를 메타 옵션 를 통해 덮어씌울 수 있는 이름으로 참조한다는 것을 명심하세요. 따라서 만약 cog를 제거하고자 한다면 다음과 같이 해야 합니다.

bot.remove_cog('Greetings')

Cogs 사용하기

방금 우리가 cog를 이름으로 제거했듯이, 우린 그것을 이름으로도 검색할 수 있습니다. 이는 우리가 cog를 데이터를 공유하기 위한 명령어 내부의 프로토콜로 사용할 수 있게 합니다. 예를 들어:

class Economy(commands.Cog):
    ...

    async def withdraw_money(self, member, money):
        # implementation here
        ...

    async def deposit_money(self, member, money):
        # implementation here
        ...

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):
        """Gambles some money."""
        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)

특별한 메소드

Cogs가 점점 복잡해지고 많은 명령어를 가지면서, cog 또는 봇을 통째로 커스터마이즈 하고 싶을 때가 찾아옵니다.

이는 다음과 같습니다:

레퍼런스를 방문해 더 자세한 정보를 찾아볼 수 있습니다.

메타 옵션

Cog의 중심에는 다양한 옵션들과 몇몇 행동을 커스터마이즈 할 수 있는 메타클래스 commands.CogMeta 가 있습니다. 이를 수행하기 위해서, 키워드 인자들을 클래스 정의 줄에 전달하세요. 예를 들어, cog의 이름을 바꾸기 위해서는 name 키워드 매개변수를 다음과 같이 전달합니다:

class MyCog(commands.Cog, name='My Cog'):
    pass

설정할 수 있는 더 많은 옵션을 보시려면, 문서의 commands.CogMeta 를 참고해주세요.

검사

Cogs가 궁극적으로 클래스이기 때문에, 우리는 cog의 특정한 속성들을 검사하는데 도움을 주는 몇 가지 도구를 가지고 있습니다.

커맨드들의 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)