Must function defs appear earlier than calls?

David M. Cooke cookedm+news at physics.mcmaster.ca
Mon May 3 23:20:18 EDT 2004


At some point, SeeBelow at SeeBelow.Nut wrote:

> I'm using Tkinter, creating buttons and scales.  One of the buttons
> should have a command option to execute a function that initializes some
> class objects.  These objects take a scale object as one of their
> initialization parameters, So I have to create the class objects after I
> create the scales.
>
> It seems that I must create the button that calls the initialization
> function after that, or else the function assigned to the command option
> is undefined.
>
> But I want to create the button first, so that it appears near the top
> of my frame.
>
> I hope that's clear.  Now you see why I didn't describe that in my
> original post!

Some actual code would make what you're trying to do clearer. Here's
my guess:

def stuff(master):
    scale1 = Scale(master)
    scale1.pack()
    scale2 = Scale(master)
    scale2.pack()
    def init_classes(scales=[scale1, scale2]):
        ... stuff ...
    button = Button(master, command=init_classes)
    button.pack()

and what you'd like is

def stuff():
    # doesn't work as scale1 and scale2 haven't been assigned yet
    def init_classes(scales=[scale1, scale2]):
        ... stuff ...
    button = Button(master, command=init_classes)
    button.pack()
    scale1 = Scale(master)
    scale1.pack()
    scale2 = Scale(master)
    scale2.pack()

You could use nested scopes like this:

def stuff():
    def init_classes():
        scales = [scale1, scale2]
        ... stuff ...
    button = Button(master, command=init_classes)
    button.pack()
    scale1 = Scale(master)
    scale1.pack()
    scale2 = Scale(master)
    scale2.pack()

Then, scale1 and scale2 aren't looked up until init_classes() is
actually called, and the values are taken from the namespace of
stuff(). By the time init_classes() is called, they should be assigned.

Alternatively, you could move stuff() into a class, and assign scale1
and scale2 as attributes of that class. init_classes should then be a
method of the class.

-- 
|>|\/|<
/--------------------------------------------------------------------------\
|David M. Cooke
|cookedm(at)physics(dot)mcmaster(dot)ca



More information about the Python-list mailing list