Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access class properties or methods from within a commands.Command

I'm building a Discord bot. The bot should store some information into some internal variables to be accessed at a later time. To do so I'm structuring it as a class (as opposed to many examples where the commands are outside a class definition). However, I discovered that when you use the @commands.command(name='test') decorator, the method becomes a kind of "static" method and no longer receives the object as first input.

Given this, is there any way I can access class properties (such as an_instance_property in the example below) and/or class methods (such as a_class_method in the example below)?

If this is the wrong approach, what could be a better approach for a bot with an internal state?

import discord
from discord.ext import commands

with open('TOKEN', 'r') as f:
    TOKEN = f.read()

class mybot(commands.Bot):
    def __init__(self):
        intents = discord.Intents.default()
        super().__init__(command_prefix="!", intents=intents)
        self.add_command(self.test)

        self.an_instance_property = [] # <----

    def a_class_method(x): # <----
        return x

    @commands.command(name='test')
    async def test(ctx, *args):
        # How can I access self.an_instance_property from here?
        # How can I call self.a_class_method from here?
        return

bot = mybot()
bot.run(TOKEN)
like image 212
Luca Avatar asked Jan 21 '26 22:01

Luca


1 Answers

My recommendation is that you avoid defining commands inside your bot class. There is a more appropriate way to do this, which is using cogs/extensions. See this topic where commands are created in a separate file (extension) and only loaded into the bot class: https://stackoverflow.com/a/78166456/14307703

Also know that the Context object always carries the instance of your bot. So you can access all the properties of the class like this:

class MyBot(commands.Bot):
    def __init__(self):
        intents = discord.Intents.default()
        super().__init__(command_prefix="!", intents=intents)
        self.add_command(self.test)

        self.an_instance_property = [] # <----

    def a_class_method(x): # <----
        return x

    @commands.command(name='test')
    async def test(ctx, *args):
        # How can I access self.an_instance_property from here?
        print(ctx.bot.an_instance_property)   # <----
        return   
like image 142
Hazzu Avatar answered Jan 24 '26 10:01

Hazzu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!