Tom Kwak
Tom Kwak

Reputation: 1

A trouble with python 'self' argument in functions

This is the code for a simple test:

class ECollector:
    #error msg collector
    #this class should be used as 'global'
    msgs = []
    def addmsg(self,msg):
        self.msgs.append(msg)
    def clear(self):
        self.msgs = []

class test(ECollector):
    dcodes = []
    ECollector
    def new(self):
        ECollector.addmsg("test!")

And this is what I ran on the python console (BTW, I'm using pyscripter 2.3 and Python 3.12)

>>>a = test()
>>>a.new()

and the following is what I got:

Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "C:\...\test.py", line 14, in new
    ECollector.addmsg("test!")
TypeError: addmsg() takes exactly 2 positional arguments (1 given)

I'm a newbie to python...and I'm rather confused about this whole thing;;; I thought the 'self' argument is something you don't need to fill-up when calling a def function.

Please rescue this poor newbie from this troublesome 'phenomenon' by giving him solutions. Thank you :)

Upvotes: 0

Views: 2856

Answers (3)

Smashery
Smashery

Reputation: 59663

The way in which you are calling ECollector.addMsg looks like you're using it as a python static method, which means it won't pass through a "self" parameter (let me know if you're a newcomer to programming languages in general and don't understand what a static method is). However, my guess is that you want to use it as an instance method rather than as a static method.

Instead, you probably want to do it as follows:

self.addmsg("test!")

Upvotes: 1

SingleNegationElimination
SingleNegationElimination

Reputation: 156188

There's lots of things that might be wrong with this. lets start at the top. It looks like you are really just using ECollector as a namespace to group some functions. That's ok, but you want to make a call to ECollector.some_method you need to change things around a bit, by making those methods into class methods:

class ECollector:
    """error msg collector
    this class should be used as 'global'"""

    msgs = []

    @classmethod
    def addmsg(cls,msg):
        cls.msgs.append(msg)

    @classmethod
    def clear(cls):
        cls.msgs = []

This means that any time you invoke addmsg or clear, they get an implicit first argument of the class itself. In this particular way that i've converted it, each subclass will get its own msgs. If you want all of the subclasses to share a single msgs attribute, then you can change cls to ECollector

Also, you will want to change your subclass around just a little bit, because you are subclassing from ECollector, but then calling its methods directly. You can do this instead:

class test(ECollector):
    dcodes = []
    def new(self):
        self.addmsg("test!")

Upvotes: 2

Mark Byers
Mark Byers

Reputation: 838376

You have defined addmsg to be an instance method. You probably meant self.addmsg("test!") instead of ECollector.addmsg("test!").

Upvotes: 3

Related Questions