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’

Asked By: Razzer

||

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:

  1. Change InviteModule init to accept GiftBot
  2. 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
Answered By: user19513069
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.