全局变量
大家来看下面一段代码:
from tkinter import *
def handler(text):
print(text+variable)
root.quit()
variable = " Lambda!"
root = Tk()
Button(root, text="Hello world!", command=(lambda: handler("Hello"))).pack()
root.mainloop()
这里代码处理器函数设置成带一个参数的函数,并用lambda表达式传入字符串"Hello",而处理器函数使用全局变量variable和参数text,运行一下,发现并没有报错,说明处理器函数是可以直接指向全局变量的。
用默认参数传入封闭作用域的值
大家看一下下面这段代码,代码中按钮在函数内部创建而不是在文件开头,变量variable不再是全局变量,而限于函数内部的封闭作用域,看上去就像它会在函数退出后、回调事件发生前消失,然后运行lambda代码:
from tkinter import *
def handler(text, tkin):
print(text)
tkin.quit()
def makegui():
variable = "Hello Lambda!"
root = Tk()
Button(root, text="Hello world!", command=(lambda: handler(variable, root))).pack()
makegui()
mainloop()
幸运的是,python的封闭作用域引用类型意味着,局部作用域内包含lambda函数的variable值会自动保留,并在按钮按下事件发生时使用。
为了将封闭作用域内的使用显示出来,我们在封闭作用域内用默认参数的值来注册变量的值,即使封闭函数已返回。例如:
from tkinter import *
def handler(text, tkin):
print(text)
tkin.quit()
def makegui():
variable = "Hello Lambda!"
root = Tk()
Button(root, text="Hello world!", command=(lambda var=variable: handler(var, root))).pack()
makegui()
mainloop()
上面这段代码中,在lambda运行时,默认参数被赋值和保存(不是在它生产函数后来调用),在事件处理期间,这是一种显式记住稍后必须访问对象的方法。由于稍后tkinter调用lambda函数时候不带参数,会使用它所有的默认值。
自动引用传入封闭作用域的值
尽管可以使外部依赖变得更加明显,默认值通常不要求,在理想的代码实践中默认值也不扮演这个角色。而是由lambda延迟对处理器的调用并提供额外处理器参数。Lambda在作用域内使用的变量是自动保留的,即使封闭函数退出后。