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)
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