[Tutor] Self, Scopes and my unbelievable muddleheadedness.

Alan Gauld alan.gauld at btinternet.com
Fri Oct 27 00:25:25 CEST 2006


> I ran onto the problem of the dictionary being changed globally, 
> when I
> thought that use of "self" meant that any changes to that data were 
> limited
> to the scope of the method in that particular class

No, but you know that now :-)

Let me try an alternative explanaytion for self, since we already had
a discussion about self recently...

self is simply a pointer to the object whose method is being called.
Lets try writing some OO code without using Pythons OOP
mechanism and see if we can spot why we need self (whether
implicitly or explicitly).

First we need a way to create objects since we dont have
classes...so we write a function that returns a dictionary.
We'll make it simple and have a message class that stores
a string and has a display method.

def display(aMessage):
    print aMessage['text']

def Message(theText):
    theObject = {}
    theObject['text'] = theText
    return theObject

Now we create a couple of instances and display them:

m1 = createMessage('Good morning')
m2 = createMessage('Hello world')

display(m1)
display(m2)

Notice how we need to pass the instance that we want
to display into the display function?

Now lets write the same thing using real OOP:

class Message:
    def __init__(self, theText):
        self.text = theText
    def display(self):
        print self.text

m1 = Message('Good morning')
m2 = Message('Hello world')
Message.display(m1)
Message.display(m2)

If you compare the definition of the display function and
the definition of the display method can you see the similarity,
and the correspondence of self to aMessage?

Now look at the two calls to display in the real OOP example.
Can you see the similarity to the calls to display in the non OOP
version?

Again can you see the correspondence between the values
passed in to the function and the values passed via the class.
In both cases its m1,m2, ie the instances we created.
In both cases the function needs those values to know
which objects message it should print.

Finally we have the more conventionalOOP notation for calling
methods:

m1.display()
m2.display()

These are exactly the same as the previous calls via the
Message class, but are more intuitive (once you  start
feeling comfortable with OOP notation as used with strings
and the like)

I've never tried explaining self with that set of examples so
it may have confused things even more! But maybe its more
conventional approach to functions v methods might make sense.

The final caveat is that message dispatch gets more complex
when you factor in inheritance so the simple non OOP example
breaks down fairly quickly...

HTH,


-- 
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld




More information about the Tutor mailing list