Python, __init__ and self confusion

initpythonself

Alright, so I was taking a look at some source when I came across this:

>>> def __parse(self, filename):
...         "parse ID3v1.0 tags from MP3 file"
...         self.clear()
...         try:
...             fsock = open(filename, "rb", 0)
...             try:
...                 fsock.seek(-128, 2)
...                 tagdata = fsock.read(128)
...             finally:
...                 fsock.close()
...             if tagdata[:3] == 'TAG':
...                 for tag, (start, end, parseFunc) in self.tagDataMap.items():
...                     self[tag] = parseFunc(tagdata[start:end])
...         except IOError:
...             pass
... 

So, I decided to test it out.

 >>> __parse("blah.mp3")

And, I received this error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __parse() takes exactly 2 arguments (1 given)

This wouldn't be the first time I've encountered this, I keep thinking I'm meant to include self in the argument parameter list, but I know that that's not right. Could someone explain to me why this happens a lot with code I try to play around with, I suppose its due to my level of understanding about the terms, I barely even understand what init or self does, or why it's relevant. def x(b): print b is the same as def x(self, b): self.b = b print self.b isn't it? Why does it matter so much!

I just want a basic explanation, so I can get this out of my mind,thanks.

Best Solution

The def __parse was inside some class definition.

You can't pull the method defs out of the class definitions. The method function definition is part of the class.

Look at these two examples:

def add( a, b ):
    return a + b

And

class Adder( object ):
    def __init__( self ):
        self.grand_total = 0
    def add( self, a, b ):
        self.grand_total += a+b
        return a+b

Notes.

  1. The function does not use self.

  2. The class method does use self. Generally, all instance methods will use self, unless they have specific decorators like @classmethod that say otherwise.

  3. The function doesn't depend on anything else else.

  4. The class method depends on being called by an instance of the class Adder; further, it depends on that instance of the class Adder having been initialized correctly. In this case, the initialization function (__init__) has assured that each instance of Adder always has an instance variable named grand_total and that instance variable has an initial value of 0.

  5. You can't pull the add method function out of the Adder class and use it separately. It is not a stand-alone function. It was defined inside the class and has certain expectations because of that location inside the class.