29
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【discord.py 2.0】Cogについて理解する

Last updated at Posted at 2020-08-06

この記事は発展的な内容です。
初心者の方でも簡単に理解できるよう心がけて説明をしたつもりではありますが、Pythonやdiscord.pyをあまり理解できていない方は先にそちらを理解することを強く推奨します。

はじめに

2023年8月に記事をかなり書き換え、簡単な書き方からCogの仕組みまで理解できるようになりました。

この記事を読もうとしているそこのあなた!!
ちょっと待ってください!!
すでにドキュメントは読んでいますか??

読んでいない場合は下のリンクからすぐに読んできてください。読んでも理解ができなかった場合や、詳しい仕組みが知りたい場合はこの記事を読み進めてください。

この記事では仕組みなど初心者には難しいと思われる場所を、下のように折りたたんであります。詳しい仕組みが知りたい!という方はぜひクリックして読んでみてください。

クリックしてネ!

( ᐛ👐)パァ

そもそも Cog(コグ) って?

Bot開発においてコマンドやリスナー、いくつかの状態を一つのクラスにまとめてしまいたい場合があるでしょう。コグはそれを実現したものです。
https://discordpy.readthedocs.io/ja/latest/ext/commands/cogs.html

公式ドキュメントにも書いてある通り、CogはBotのプログラムをいくつかに分割するために使用します。
大きなBotの場合、一つのファイルにまとめると3000行とか大変なことになりますからね()
また後述のExtensionを使うとBotの再起動なしにプログラムを書き換えることもできます。

Cogを使う際の書き換え

コマンド

Cogを使わないときはコマンドを定義する際に以下のように書きますが、

@bot.command()
async def test(ctx):
    pass #処理内容

Cog内でコマンドを定義するときは以下のように書きます。

@commands.command()
async def test(self, ctx):
    pass #処理内容

違いは@bot.~@commands.~なったのと、引数にselfが追加されたことぐらいですかね。

イベント

Cogを使わないときはイベントを定義する際に以下のように書きますが、

@bot.event
async def on_ready():
    pass #処理内容

Cog内でイベントを定義するときは以下のように書きます。

@commands.Cog.listener()
async def on_ready(self):
    pass #処理内容

違いは@bot.event@commands.Cog.listener()になったことと、さっきと同じように引数にselfが追加されたことですね。

変数botの使い方

Cogを使わないときはBotのデータにアクセスする際に以下のように書きますが、

bot

Cog内でアクセスするときは以下のようになります。

self.bot

違いはselfを書かなければいけなくなったってことぐらいですね。

さっきから出てくるselfって何者??

selfはdiscord.pyの機能ではなく、PythonのClassの機能になります。
selfを使うことで同一クラス内の関数でデータを共有することができます。
詳しくは下の記事を読んでみてください。

https://qiita.com/baby-0105/items/c7b2d9b22780a326e4b7

Cogの追加

同一ファイルの時

import discord
from discord.ext import commands

bot = commands.Bot(command_prefix="!")

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

    @commands.command()
    async def test(self, ctx):
        await ctx.send("test!")

@bot.event
async def setup_hook():
    await bot.add_cog(MyCog(bot))

こんな感じになります。

@bot.event
async def setup_hook():
    await bot.add_cog(MyCog(bot))

の部分でCogを読み込んでいます。

Cog名(上でいうところのMyCog)に特に決まりはないため、好きに決めることができます。

__init__ってなに??

これも、Pythonの機能になります。
Classの生成後に実行される関数です。
これを使うことでClassが生成されたとき(≒Cogが実行されたとき)の処理を書くことができます。
詳しくは下の記事を読んでみてください。

https://qiita.com/ishigen/items/2d8b6e6398743f2c8110

仕組み
  1. Botの起動後setup_hookが呼び出される。

  2. bot.add_cogでCogを追加。

別ファイルのとき

このままだと、Classに分けることはできてもファイルは一つのままです。
そこで、Classの部分を別のファイルに移してみましょう。

ファイル構成
.
┣━ main.py
┗━ sub.py

ファイル構成が上のようになっていてsub.pyにあるMyCogを読み込みたいときは以下のようにします。

main.py
import discord
from discord.ext import commands
import sub

bot = commands.Bot(command_prefix="!")

@bot.event
async def setup_hook():
    await bot.add_cog(sub.MyCog(bot))
sub.py
import discord
from discord.ext import commands

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

    @commands.command()
    async def test(self, ctx):
        await ctx.send("test!")

main.pyを実行し、testコマンドを実行するとtest!と返ってきます。

仕組み
  1. main.pyimport subsub.pyを読み込む。

  2. bot.add_cogsub.pyにあるMyCogを読み込む。

また、上記以外のディレクトリの場合も同じようにimportを使うことで読み込みできます。
詳しくは、下の記事をご覧ください。

Extension

Extensionとは上でも言いましたが、Botの再起動なしにプログラムを書き換えることをできるようにする機能のことです。

一般的にCogとExtensionを同時に使うことが多いので、Cog≒Extensionと誤解しやすいですが、別の機能です。

ファイル構成
.
┣━ main.py
┗━ sub.py

ファイル構成が上のようになっている場合、下のようにすることでExtensionを使えるようになります。

main.py
import discord
from discord.ext import commands

bot = commands.Bot(command_prefix="!")

@bot.event
async def setup_hook():
    await bot.load_extension("sub")
sub.py
import discord
from discord.ext import commands

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

    @commands.command()
    async def test(self, ctx):
        pass

async def setup(bot):
    await bot.add_cog(MyCog(bot))

main.pyを実行し、testコマンドを実行するとtest!と返ってきます。

仕組み
  1. main.pybot.load_extensionsub.pyを読み込む。

  2. sub.pysetup関数が読み込まれる。

  3. === ここまでがExtensionの機能 ===

  4. bot.add_cogsub.pyにあるMyCogを読み込む。

ファイル構成
.
┣━ main.py
┗━ cog
 ┗━ sub.py

ファイル構成が上のようになっている場合、await bot.load_extension("cog.sub")で読み込みできます。

最後に

わからないこと、追加してほしいこと、誤字脱字等があれば遠慮なくコメントしてください。
ただ、忙しいので見れない可能性もあります。予めご了承ください。

29
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?