How can I get a self variable from another class?
Question:
My problem is that I need to get the self.tracker
variable from the gift_bot.py
file inside the cogs/invite_moduly.py
file. But sadly, I don’t know a way to do that. I tried a few methods like self.bot.tracker
, tracker
and more, but none worked.
How can I access this variable in invite_module.py
?
File gift_bot.py
class GiftBot(commands.Bot):
def __init__(self):
self.tracker = InviteTracker(self)
super().__init__(command_prefix="*", intents=intents, case_insensitive=True)
async def on_ready(self):
try:
await self.tracker.cache_invites()
except:
pass
cogs/invite_module.py:
class InviteModule(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
self.last_member: list = []
@commands.Cog.listener("on_member_join")
async def on_member_join(self, member: discord.Member):
invite_info = await get_inviter(self.tracker, member)
With this code, I get:
Unresolved attribute reference ‘tracker’ for class ‘InviteModule’
Answers:
Assuming that you instantiate InviteModule
with bot
being a reference to an instance of GiftBot
, it would be self.bot.tracker
.
self
is used to reference the instance of the class where’s that method (by convention, it’s not a keyword, but it’s discouraged to use something other than self
). So, inside InviteModule
, self
is an object of the class InviteModule
, and inside GiftBot
, it’s an object the class GiftBot
.
If you want to reference a property of GiftBot
inside InviteModule
, you must pass an instance of GiftBot
to InviteModule
¹, which I assume you’re doing as the bot
property. So, to access it inside InviteModule
use self.bot
, and hence, the tracker would be self.bot.tracker
.
¹ Or, instead of passing the whole bot, you could pass the property itself. For instance, you could do:
class InviteModule(commands.Cog):
def __init__(self, tracker):
self.tracker = tracker
# rest of the code here
And use as:
giftBot = GiftBot()
inviteModule = InviteModule(giftBot.tracker)
I assume you want the first option, but I’m adding this for completeness.
I can be wrong, but I believe the error mentioned in the comments is actually from the IDE.
Per your comment, I suppose class Bot
does not have the field tracker. So, you could either:
- Change
InviteModule
init to accept GiftBot
- Before trying to access the field
tracker
, check if the element is an instance of GiftBot.
If there’s nothing usable in InviteModule
without the field tracker
, the first option is probably better:
class InviteModule(commands.Cog):
def __init__(self, bot: GiftBot): # or gift_bot.GiftBot, depending on how you're importing/connecting those files
self.bot = bot
# rest of the code
The second option would go something like:
class InviteModule(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
# rest of init
@commands.Cog.listener("on_member_join")
async def on_member_join(self, member: discord.Member):
if instanceof(self.bot, GiftBot):
invite_info = await get_inviter(self.bot.tracker, member)
# if not instance, define what's desired: ignore, log only, throw an error
My problem is that I need to get the self.tracker
variable from the gift_bot.py
file inside the cogs/invite_moduly.py
file. But sadly, I don’t know a way to do that. I tried a few methods like self.bot.tracker
, tracker
and more, but none worked.
How can I access this variable in invite_module.py
?
File gift_bot.py
class GiftBot(commands.Bot):
def __init__(self):
self.tracker = InviteTracker(self)
super().__init__(command_prefix="*", intents=intents, case_insensitive=True)
async def on_ready(self):
try:
await self.tracker.cache_invites()
except:
pass
cogs/invite_module.py:
class InviteModule(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
self.last_member: list = []
@commands.Cog.listener("on_member_join")
async def on_member_join(self, member: discord.Member):
invite_info = await get_inviter(self.tracker, member)
With this code, I get:
Unresolved attribute reference ‘tracker’ for class ‘InviteModule’
Assuming that you instantiate InviteModule
with bot
being a reference to an instance of GiftBot
, it would be self.bot.tracker
.
self
is used to reference the instance of the class where’s that method (by convention, it’s not a keyword, but it’s discouraged to use something other than self
). So, inside InviteModule
, self
is an object of the class InviteModule
, and inside GiftBot
, it’s an object the class GiftBot
.
If you want to reference a property of GiftBot
inside InviteModule
, you must pass an instance of GiftBot
to InviteModule
¹, which I assume you’re doing as the bot
property. So, to access it inside InviteModule
use self.bot
, and hence, the tracker would be self.bot.tracker
.
¹ Or, instead of passing the whole bot, you could pass the property itself. For instance, you could do:
class InviteModule(commands.Cog):
def __init__(self, tracker):
self.tracker = tracker
# rest of the code here
And use as:
giftBot = GiftBot()
inviteModule = InviteModule(giftBot.tracker)
I assume you want the first option, but I’m adding this for completeness.
I can be wrong, but I believe the error mentioned in the comments is actually from the IDE.
Per your comment, I suppose class Bot
does not have the field tracker. So, you could either:
- Change
InviteModule
init to acceptGiftBot
- Before trying to access the field
tracker
, check if the element is an instance of GiftBot.
If there’s nothing usable in InviteModule
without the field tracker
, the first option is probably better:
class InviteModule(commands.Cog):
def __init__(self, bot: GiftBot): # or gift_bot.GiftBot, depending on how you're importing/connecting those files
self.bot = bot
# rest of the code
The second option would go something like:
class InviteModule(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
# rest of init
@commands.Cog.listener("on_member_join")
async def on_member_join(self, member: discord.Member):
if instanceof(self.bot, GiftBot):
invite_info = await get_inviter(self.bot.tracker, member)
# if not instance, define what's desired: ignore, log only, throw an error