1

When I do my discord.py project, I found out that the following codes work well in the first time but return an attribute error for the second time (in a single run).

class Test2(commands.Cog):
    def __init__(self, dc_bot):
        self.bot = dc_bot
        self.ui = ""

    @commands.command(description="get avatar")
    async def getavatar(self, ctx, *, content: str):
        avatar = self.bot.user.avatar_url

        self.ui += content
        await ctx.send(content)
        await ctx.send(avatar)

        self.__init__(self) # reset the values 

First time it works well.
Second time it will say: AttributeError: 'Test2' has no attribute 'user'
I guess because I want to reset self.ui for the next run.
And if there are a lot of "self" in my init function that I need to use, I thought (before) that it is a good idea to just called the init function. But running again self.ui = dc_bot will cause this problem I think. Could you explain why this would happen please?

AcK
  • 2,063
  • 2
  • 20
  • 27
TimG233
  • 535
  • 2
  • 12
  • You should add in your question the code that uses that class. This will help us understand your "First time" and "Second time" usage you talk about. – Nic3500 Oct 24 '21 at 21:38

2 Answers2

1

There's a mistake when you re-calls the init method. self.__init__(self) is actually calling Test2. __init__(self, self) . Which overrides self.bot = self thus the attribute error when you run the command a second time. Instead you want:

self.__init__(self.bot)

But this isn't a good solution, instead you should have a "reset" helper method that does the resetting,and you call the helper method instead of init. Since normally, once the class is initiated, you don't want to call the init method again.

Taku
  • 31,927
  • 11
  • 74
  • 85
  • Really helpful! So, is "not calling __init__ function again" like a good habit or normal common things that other people would do? – TimG233 Oct 24 '21 at 23:48
  • 1
    Glad I'm able to help. You should generally avoid calling `__init__` after the instance's initiated, it's not common and I would consider it as a bad habit. I also found another post that explains what I mentioned and how you can use a reset method instead: https://stackoverflow.com/a/13091370/6622817 – Taku Oct 25 '21 at 00:54
0

You are making the code way too complex try this out!

    @commands.command(description  = "get avatar")

    async def getavatar(self, ctx, *, avamember: discord.Member = None):
        userAvatarUrl = avamember.avatar_url
        await ctx.send(userAvatarUrl)
Derek
  • 98
  • 10