scoping weirdness

Paul Rubin phr-n2001 at nightsong.com
Sat Aug 25 04:35:19 EDT 2001


"Tim Peters" <tim.one at home.com> writes:
> Of course.  Try the same thing in Scheme (which you've already confessed to
> knowing <wink>):
> 
> (define (foo n)
>   (let ((a (lambda () n)))
>     (set! n (+ n 3))
>     a))
> 
> (define x (foo 1))
> 
> After that, (x) evaluates to 4 too.  

Well ok, but I thought we had a thread the other day saying Python
doesn't actually have closures :-).  Anyway I was surprised.

> Most Python programmers would write a class, though, explicitly binding an
> instance variable to the value they wanted at the time they wanted to
> capture it.  Like: (example snipped to save space)...
> 
> It's a bit more typing at the start, but more flexible in the end, because
> the state is materialized explicitly (and so open to fiddling via writing
> new methods as requirements change), rather than implicitly hidden away in
> closures.

Yes, let me go up a level and ask if there's a better way to do this.
It's for Tkinter--say I want several buttons that all call the same
function, giving the button text as an argument.  My code looks
something like:

    from __future__ import nested_scopes
    from Tkinter import *

    def press_button (text):
      print 'you pressed %s' % text

    def create_button (label):
      func = lambda: press_button (label)
      Button(root,text=label,command=func).pack()
      # if I put more stuff here and set label to something new,
      # the button doesn't do what I expected.

    root = Tk()
    create_button ("fear")
    create_button ("surprise")
    create_button ("ruthless efficiency")

The point is that from the Tkinter docs it looks like the Button
widget really wants its command parameter to be a function with no
args, so I needed to create a lambda that would call press_button with
the arg I wanted.

What would be best is if the Button widget had a way of passing args
to its command func.  Is there something like that which I missed?

Thanks as usual.



More information about the Python-list mailing list