SV: SV: [Tutor] Stuck with classes - events [Callbacks / Function calling]

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Mon, 8 Oct 2001 23:06:46 -0700 (PDT)


On Fri, 5 Oct 2001, Danny Kohn wrote:

> | Fran: tutor-admin@python.org [mailto:tutor-admin@python.org]For Sean
> | 'Shaleh' Perry
> | Skickat: den 5 oktober 2001 16:46
> | Till: Danny Kohn
> | Kopia: Python Tutor mailing list
> 
> | Consider this.  When item A gets a Ctrl+Left click it tells its 
> | parent to make it the current object.
> 
> And how is this "telling" done in practice in oop? I am very new to
> this.

I can't say that this is how wxPython does things, but in Tkinter, the GUI
"tells" us when things happen by calling some function.  I'm more familiar
with Tkinter, so I'll use it for the examples here; I'm sure that wxPython
uses similar concepts.


Here's a small program that responds to pressing a Button:

###
from Tkinter import *

def sayHello():
    print "Hello world!"

if __name__ == '__main__':
    root = Tk()
    button = Button(root, text="Press me", command=sayHello)
    button.pack()
    mainloop()
###

This program might initially seem unusual: where are we calling sayHello?  
And why is it an argument to our button?  We're not calling sayHello,
since we haven't put parens at the end, so something different must be
going on.  What is sayHello without parens?

###
>>> sayHello
<function sayHello at 0x816188c>
###

So we're passing a function, as if it were some piece of data!  The
statement:

    button = Button(root, text="Press me", command=sayHello)

could be read like this:

"""Ok, we'll make an instance of this Button.  Remember that you belong to
this root container, and that you have to display 'Press me'.

Oh, and one more thing: if we ever really do press you, we want you to
call back THIS function called 'sayHello'.  Don't call 'sayHello' now, but
just keep this in mind for future reference."""


This style of programming is called event-based programming, and it's all
based on the idea of "callbacks".  A callback is just a fancy name for a
function.

Event-based programming is a little weird because we're not in "control"
most of the time: some external thing, like the GUI, manages things.  
However, this manager is able to pass control back to us at key moments,
by calling our functions.  And that's where control passes back to us.

We can "pass control" to an instance if we call that instance's methods.  
For example:

###
class A:
    def respond(self):
        print "I'm in A."
 
class B:
    def __init__(self, friend):
        self.friend = friend

    def respond(self):
        print "I'm in B."
        print "%s, now you talk!" % self.friend
	print "But what am I calling?  %s" %  self.friend.respond
        self.friend.respond()
	print "I'm back in B."
###


Let's take a look:

###
>>> a = A()
>>> b = B(a)
>>> a.respond()
I'm in A.
>>> b.respond()
I'm in B.
<__main__.A instance at 0x81d53d4>, now you talk!
But what am I calling?  <method A.respond of A instance at 0x81d53d4>
I'm in A.
I'm back in B.
###

Function calling is the key to all of this; as soon as you see it, it'll
hit like a blinding flash of "Eureka!"  Another part of the Eureka thing
is that you'll eventually see that methods are just functions (with a
little dressing to make them spicy.)

Play around with it, and keep asking questions, and we'll do what we can
to accelerate the Bathtub moment.


By the way, I did a search on the web, and found a pretty nice overview on
how to do GUI programming here:

    http://www.wag.caltech.edu/home/rpm/python_course/Lecture_6.pdf

It's Tkinter based, but I think it'll still be useful for you.  Good luck!