[Tkinter-discuss] Button command callback question -- Part 2

Lion Kimbro lionkimbro at gmail.com
Mon Jul 18 20:59:00 CEST 2011


  I would also add a caution:

  If you assign x *anywhere* within the function, a prior use will fail...

  def foo():
      print x    # raises UnboundLocalError,
      x = 10   # ...because the interpreter knows that x is local.

  Only unassigned values are searched for in the global namespace, if not
locally declared.

  I think the reason it's like this, is to keep variables in one function in
one scope,
  for sanity's sake.


On Mon, Jul 18, 2011 at 11:21 AM, Michael Lange <klappnase at web.de> wrote:

> Hi,
>
> Thus spoketh GKalman <kalman_g at msn.com>
> unto us on Mon, 18 Jul 2011 05:24:53 -0700 (PDT):
>
> (...)
> >
> > #NOTE that it works even when the mainloop() method below is commented
> > out!!!!
> > #root.mainloop()
> > #===================================================================
> >
> > so: if
> > (1) there is no mainloop()
> > (2) x=11 is declared in the MAIN part
> > (3) command=doIt() has no argument
> > (4) doIt() fn appears ahead of the x=11 statement
> >
> > My Question is: why x=11 is within the scope of the doIt() callback fn?
> >
>
> Here when root.mainloop() is commented out, the call to
>  $ python test.py
> immediately returns ;) Of course you don't need to explicitely call
> mainloop() when you run python in interactive mode from a terminal.
>
> Besides this I cannot see anything surprising in the behavior of the
> code example. When you define x=11 you add an object "x" to the global
> namespace. When doIt() is called and the print x command is being
> executed, the interpreter will first look if an object x is defined
> within the function's namespace and then look within the global namespace
> for such an object. Only when it cannot find such an object in any
> available namespace an error will be raised.
> Of course the contents of the function body are not evaluated before the
> function is actually called. So it is not important if doIt is defined
> before x , but only if x is already defined when doIt() is called.
>
> Maybe it helps you understand what happens if you change your example a
> little. If you change the doit() definition like
>
>  def doIt():
>     x = 2
>     print x
>
> it will print 2 instead of 11 . It is important to understand that the
> "outer" x will not be changed by calls to this function as you can verify
> by e.g. adding a second button that will call the original version of
> your doIt() function, or by changing it a little  more:
>
> def doIt():
>     print x
>     def foo():
>         x=2
>         print x
>     foo()
>
> Now it will print first 11, then 2 , but without overriding the "outer" x,
> as you can see by repeatedly pressing the button.
>
> If you want to change the "outer" (=global) x , you need to add the
> "global" statement:
>
> def doIt():
>     print x
>     def foo():
>         global x
>         x+=1
>         print x
>     foo()
>
> I hope this helps
>
> Michael
>
>
> .-.. .. ...- .   .-.. --- -. --.   .- -. -..   .--. .-. --- ... .--. . .-.
>
> Death.  Destruction.  Disease.  Horror.  That's what war is all about.
> That's what makes it a thing to be avoided.
>                -- Kirk, "A Taste of Armageddon", stardate 3193.0
> _______________________________________________
> Tkinter-discuss mailing list
> Tkinter-discuss at python.org
> http://mail.python.org/mailman/listinfo/tkinter-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tkinter-discuss/attachments/20110718/ab887fdd/attachment.html>


More information about the Tkinter-discuss mailing list