使用不带 cogs 的 discord.py 是不是可以实现 OOP?

Posted

技术标签:

【中文标题】使用不带 cogs 的 discord.py 是不是可以实现 OOP?【英文标题】:Is OOP possible using discord.py without cogs?使用不带 cogs 的 discord.py 是否可以实现 OOP? 【发布时间】:2020-12-03 19:26:14 【问题描述】:

最近几天,我一直在尝试将用 discord.py 编写的不和谐机器人的结构调整为更面向 OOP 的结构(因为周围存在功能并不理想)。

但我发现的问题比我想象的要多得多。问题是我想将所有命令封装到一个单个类中,但我不知道要使用哪些装饰器以及我必须继承哪些类以及如何继承。

到目前为止,我所取得的成果是下面的 sn-p 之类的代码。它会运行,但在执行命令时会抛出类似

的错误

discord.ext.commands.errors.CommandNotFound:找不到命令“状态”

我使用的是 Python 3.6。

from discord.ext import commands


class MyBot(commands.Bot):

    def __init__(self, command_prefix, self_bot):
        commands.Bot.__init__(self, command_prefix=command_prefix, self_bot=self_bot)
        self.message1 = "[INFO]: Bot now online"
        self.message2 = "Bot still online "

    async def on_ready(self):
        print(self.message1)

    @commands.command(name="status", pass_context=True)
    async def status(self, ctx):
        print(ctx)
        await ctx.channel.send(self.message2 + ctx.author)


bot = MyBot(command_prefix="!", self_bot=False)
bot.run("token")

【问题讨论】:

【参考方案1】:

要注册命令,您应该使用self.add_command(setup),但您不能在setup 方法中使用self 参数,因此您可以执行以下操作:

from discord.ext import commands
    
class MyBot(commands.Bot):
    
    def __init__(self, command_prefix, self_bot):
        commands.Bot.__init__(self, command_prefix=command_prefix, self_bot=self_bot)
        self.message1 = "[INFO]: Bot now online"
        self.message2 = "Bot still online"
        self.add_commands()
    
    async def on_ready(self):
        print(self.message1)
    
    def add_commands(self):
        @self.command(name="status", pass_context=True)
        async def status(ctx):
            print(ctx)
            await ctx.channel.send(self.message2, ctx.author.name)
        
        self.add_command(status)
    
bot = MyBot(command_prefix="!", self_bot=False)
bot.run("token")

【讨论】:

感谢您的回答,它真的帮助了我!但是,我认为该方法的名称不应该是“add_commands”,因为 Bot 类中已经有一个名为“add_command”的方法(这让我困惑了 5 分钟:P)。 我很高兴它有帮助! 如果有人发现此问题并收到 discord.ext.commands.errors.CommandRegistrationError: The command status is already an existing command or alias.discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: send() takes from 1 to 2 positional arguments but 3 were given 错误,请尝试删除 self.add_command(status) 并将发送行更新为 await ctx.channel.send(f'self.message2, ctx.author.name') 这对我有用。 当命令被称为status 时为什么需要name="status"【参考方案2】:

我有同样的问题,今天找到了这个解决方法。但是我找到了一个类似的解决方案,没有使用添加命令的方法:

from discord.ext import commands

class DiscordBot(commands.Bot):
    def __init__(self):
        super().__init__(command_prefix="!")

        @self.command(name='test')
        async def custom_command(ctx):
            print("Hello world !")

    async def on_ready(self):
        print(f"Bot self.user.display_name is connected to server.")

bot = DiscordBot()
bot.run("token")

【讨论】:

以上是关于使用不带 cogs 的 discord.py 是不是可以实现 OOP?的主要内容,如果未能解决你的问题,请参考以下文章

@bot.event 在一个 cog discord.py

如何使用 Discord.py Cogs 使 Discord Bot 加入语音频道并在成员加入频道时播放音频文件

discord.py - 检查是不是找不到子命令

负载侦听器上的 Discord.py Cog

Discord py cogs 不加载命令

Discord.py music_cog,机器人加入频道但不播放声音