[Python编程(第4版)].(Programming.Python.4th.Edition).Mark.Lutz.文字版

(yzsuai) #1

not change to a value you don’t expect after the nested function is created. You cannot
generally reference enclosing scope loop variables within a nested function, for exam-
ple, because they will change as the loop progresses. In most other cases, though, en-
closing scope variables will take on only one value in their scope and so can be used
freely.


We’ll see this phenomenon at work in later examples that construct larger GUIs. For
now, remember that enclosing scopes are not a complete replacement for defaults;
defaults are still required in some contexts to pass values into callback functions. Also
keep in mind that classes are often a better and simpler way to retain extra state for use
in callback handlers than are nested functions. Because state is explicit in classes, these
scope issues do not apply. The next two sections cover this in detail.


Bound Method Callback Handlers


Let’s get back to coding GUIs. Although functions and lambdas suffice in many cases,
bound methods of class instances work particularly well as callback handlers in GUIs—
they record both an instance to send the event to and an associated method to call. For
instance, Example 7-14 shows Examples 7-12 and 7-13 rewritten to register a bound
class method rather than a function or lambda result.


Example 7-14. PP4E\Gui\Intro\gui3c.py


import sys
from tkinter import *


class HelloClass:
def init(self):
widget = Button(None, text='Hello event world', command=self.quit)
widget.pack()


def quit(self):
print('Hello class method world') # self.quit is a bound method
sys.exit() # retains the self+quit pair


HelloClass()
mainloop()


On a button press, tkinter calls this class’s quit method with no arguments, as usual.
But really, it does receive one argument—the original self object—even though tkinter
doesn’t pass it explicitly. Because the self.quit bound method retains both self and
quit, it’s compatible with a simple function call; Python automatically passes the
self argument along to the method function. Conversely, registering an unbound in-
stance method that expects an argument, such as HelloClass.quit, won’t work, be-
cause there is no self object to pass along when the event later occurs.


Adding User-Defined Callback Handlers | 391
Free download pdf