[Tutor] Variables of Variables

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Mon Jan 22 18:10:11 CET 2007


> Actually, I started off with a dictionary with a bunch of parameters. To
> give you some background, I writing my
> first GUI, and using the parameters in a dictionary to control what box the
> GUI displays next. So, it looks
> something that looks like this:
>
> data={'position':'middle',
>       'next':'self.add_entry_db (widget,None)',
>       'previous':'self.add_entry(widget,None)'}

Hi Tino,


Ok, so it looks like you're trying to encode the idea that, when 'next' is 
pressed, then the content of:

     'self.add_entry_db (widget,None)'

should fire off.  A good way to say this in Python is to say that 'next' 
refers to a function.


Let's do a quick refresher.  Functions can be held without them 
immediately firing off.  For example:

###############################
>>> def square(x):
...     return x * x
...
>>> square
<function square at 0xb7da9d84>
###############################

You may have left out the parentheses by accident and wondered why Python 
lets us do this: isn't it obvious that functions are meant to be called?


But this time, we are going to leave off the parens deliberately.  *grin* 
If you twist your mind enough, you can analogize this with "numbers" and 
"strings" by thinking of "functions" as just another data type.

And like those other data types, we can actually stuff functions in as 
dictionary values:

############################
>>> cmds = { '^2' : square,
...          '*2' : double }
############################

This 'cmds' is a dictionary from strings to functions!  And, weird as it 
might look, we can do the following:

###############################
>>> cmds['^2']
<function square at 0xb7da9d84>
>>>
>>> cmds['^2'](42)
1764
>>> cmds['*2'](42)
84
###############################

That is, we pull the function out of the dictionary, and then call it. 
That's the key idea we can take advantage of for your problem.



Looking back at the definition of data:

###############################################
data={'position':'middle',
       'next':'self.add_entry_db (widget,None)',
       'previous':'self.add_entry(widget,None)'}
###############################################

we can change things a bit, and make 'next' and 'previous' refer to 
functions that eat widgets:

###################################################
     ## [in the context where data is being defined]
     def next_cmd(widget):
         self.add_entry_db(widget,None)

     def previous_cmd(widget):
         self.add_entry(widget, None)

     data = { 'position' : 'middle',
              'next' : next_cmd,
              'previous' : previous_cmd }
###################################################


That is, we're building two functions on the fly and just adding them to 
our data.



Later on, when we are in your callback, the Data values are going to be 
functions that are just waiting to fire.


> The dictionary called data gets passed to a button maker function that 
> will show various buttons depending on the position value in the data 
> dictionary. The clicked signal is then hooked up to a callback function 
> (I think that's what you call it), and the next/previous values get sent 
> up to various functions. An example one of these various functions is:
>
>   def add_next_button(self,widget,Data=None):
>       self.dbTableName=self.addEntryBox.get_text()
>       self.addWin.destroy()
>       if type(Data) == type(None):
>           print "Why are we here?"
>           exit()
>       print Data
>       Data()


Yup.  With the changes above, this becomes:

###################################################
    def add_next_button(self,widget,Data=None):
        self.dbTableName=self.addEntryBox.get_text()
        self.addWin.destroy()
        if type(Data) == type(None):
            print "Why are we here?"
            exit()
        Data(widget)
###################################################



> where the Data variable is 'self.add_entry_db(widget,None)'. How do I 
> pass the Data variable to the add_next_button so that the contents 
> itself the data variable can execute?

Learn how to treat functions as data.  That's really what you are asking 
for.  If you have questions about this, please feel free to ask.


More information about the Tutor mailing list